1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use crate::{Compress, Derive};
use group::{ff::Field, Group, UncompressedEncoding};
use pg_curve::{G1Projective, G2Projective, Gt, Scalar};
use rand::{CryptoRng, RngCore};
use subtle::CtOption;
use tiny_keccak::Hasher;
pub(crate) const GT_BYTES: usize = 288;
pub(crate) const G1_BYTES: usize = 48;
pub(crate) const G2_BYTES: usize = 96;
pub(crate) const SCALAR_BYTES: usize = 32;
pub(crate) const ID_BYTES: usize = 64;
#[inline(always)]
pub fn rand_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Scalar {
Scalar::random(rng)
}
#[inline(always)]
pub fn rand_g1<R: RngCore + CryptoRng>(rng: &mut R) -> G1Projective {
G1Projective::random(rng)
}
#[inline(always)]
pub fn rand_g2<R: RngCore + CryptoRng>(rng: &mut R) -> G2Projective {
G2Projective::random(rng)
}
#[inline(always)]
pub fn rand_gt<R: RngCore + CryptoRng>(rng: &mut R) -> Gt {
Gt::random(rng)
}
pub fn bits<'a>(slice: &'a [u8]) -> impl Iterator<Item = subtle::Choice> + 'a {
slice
.iter()
.rev()
.zip((0..8).rev())
.map(|(x, i)| subtle::Choice::from((*x >> i) & 1))
}
pub fn sha3_256(slice: &[u8]) -> [u8; 32] {
let mut digest = tiny_keccak::Sha3::v256();
digest.update(slice);
let mut buf = [0u8; 32];
digest.finalize(&mut buf);
buf
}
pub fn sha3_512(slice: &[u8]) -> [u8; 64] {
let mut digest = tiny_keccak::Sha3::v512();
digest.update(slice);
let mut buf = [0u8; 64];
digest.finalize(&mut buf);
buf
}
pub fn shake256<const N: usize>(slice: &[u8]) -> [u8; N] {
let mut digest = tiny_keccak::Shake::v256();
digest.update(slice);
let mut buf = [0u8; N];
digest.finalize(&mut buf);
buf
}
pub fn rpc<Gr: UncompressedEncoding>(k: &[u8; 32], gs: &[Gr]) -> Scalar {
let mut digest = tiny_keccak::Sha3::v512();
digest.update(k);
for g in gs.iter() {
digest.update(g.to_uncompressed().as_ref())
}
let mut buf = [0u8; 64];
digest.finalize(&mut buf);
Scalar::from_bytes_wide(&buf)
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Identity(pub [u8; ID_BYTES]);
impl Default for Identity {
fn default() -> Self {
Self([0u8; ID_BYTES])
}
}
impl Derive for Identity {
fn derive(b: &[u8]) -> Identity {
Identity(sha3_512(b))
}
fn derive_str(s: &str) -> Identity {
Self::derive(s.as_bytes())
}
}
impl Identity {
#[allow(unused)]
pub(crate) fn to_scalar(self) -> Scalar {
Scalar::from_bytes_wide(&self.0)
}
}
impl Compress for Gt {
const OUTPUT_SIZE: usize = GT_BYTES;
type Output = [u8; Self::OUTPUT_SIZE];
fn to_bytes(&self) -> [u8; GT_BYTES] {
self.to_compressed()
}
fn from_bytes(bytes: &[u8; GT_BYTES]) -> CtOption<Self> {
Self::from_compressed(bytes)
}
}