1+ mod constants;
2+ mod periodic;
3+ mod utils;
4+ use ark_bls12_381:: { Bls12_381 , Fr } ;
5+ use constants:: { ROUND_CONSTANTS , ROTR } ;
6+ use ark_ff:: UniformRand ;
7+ use ark_r1cs_std:: boolean:: Boolean ;
8+ use ark_r1cs_std:: eq:: EqGadget ;
9+ use ark_r1cs_std:: { R1CSVar , ToBitsGadget } ;
10+ use ark_r1cs_std:: uint64:: UInt64 ;
11+ use ark_relations:: r1cs:: { ConstraintSynthesizer , ConstraintSystem } ;
12+ use ark_relations:: r1cs:: { ConstraintSystemRef , SynthesisError } ;
13+ use ark_std:: rand:: { thread_rng, Rng } ;
14+ use ark_std:: ops:: { BitAnd , BitXor , Not } ;
15+
116use ark_ff:: PrimeField ;
17+ use ark_r1cs_std:: alloc:: AllocVar ;
218use ark_r1cs_std:: fields:: fp:: FpVar ;
19+ use ark_r1cs_std:: uint8:: UInt8 ;
320use swiftness_field:: Fp ;
421use swiftness_field:: SimpleField ;
522use sha3:: Keccak256 ;
623use sha3:: Digest ;
24+ use crate :: keccak:: utils:: { bitand, not, rotate_left} ;
25+
26+ fn xor_2 < F : PrimeField > ( a : & UInt64 < F > , b : & UInt64 < F > ) -> Result < UInt64 < F > , SynthesisError > {
27+ a. xor ( b)
28+ }
29+
30+ fn xor_5 < F : PrimeField > (
31+ a : & UInt64 < F > ,
32+ b : & UInt64 < F > ,
33+ c : & UInt64 < F > ,
34+ d : & UInt64 < F > ,
35+ e : & UInt64 < F > ,
36+ ) -> Result < UInt64 < F > , SynthesisError > {
37+ // a ^ b ^ c ^ d ^ e
38+ //note: in aff-std 0.5, use .bitxor
39+ let ab = a. xor ( b) ?;
40+ let abc = ab. xor ( c) ?;
41+ let abcd = abc. xor ( d) ?;
42+ abcd. xor ( e)
43+ }
44+
45+ fn xor_not_and < F : PrimeField > (
46+ a : & UInt64 < F > ,
47+ b : & UInt64 < F > ,
48+ c : & UInt64 < F > ,
49+ ) -> Result < UInt64 < F > , SynthesisError > {
50+ // let nb = b.not();
51+ let nb = not ( b) ;
52+
53+ // let nbc = nb.bitand(c);
54+ let nbc = bitand ( & nb, c) ;
55+ a. xor ( & nbc)
56+ }
57+
58+ fn round_1600 < F : PrimeField > (
59+ // cs: &ConstraintSystemRef<F>,
60+ a : Vec < UInt64 < F > > ,
61+ rc : u64 ,
62+ ) -> Result < Vec < UInt64 < F > > , SynthesisError > {
63+
64+ assert_eq ! ( a. len( ) , 25 ) ;
65+
66+ // # θ step
67+ // C[x] = A[x,0] xor A[x,1] xor A[x,2] xor A[x,3] xor A[x,4], for x in 0…4
68+ let mut c = Vec :: new ( ) ;
69+ for x in 0 ..5 {
70+ c. push ( xor_5 (
71+ & a[ x + 0usize ] ,
72+ & a[ x + 5usize ] ,
73+ & a[ x + 10usize ] ,
74+ & a[ x + 15usize ] ,
75+ & a[ x + 20usize ] ,
76+ ) ?) ;
77+ }
78+
79+ // D[x] = C[x-1] xor rot(C[x+1],1), for x in 0…4
80+ let mut d = Vec :: new ( ) ;
81+ for x in 0 ..5 {
82+ d. push ( xor_2 (
83+ & c[ ( x + 4usize ) % 5usize ] ,
84+ // &c[(x + 1usize) % 5usize].rotate_left(1),
85+ & rotate_left ( & c[ ( x + 1usize ) % 5usize ] , 1 ) ,
86+
87+ ) ?) ;
88+ }
89+
90+
91+ // A[x,y] = A[x,y] xor D[x], for (x,y) in (0…4,0…4)
92+ let mut a_new1 = Vec :: new ( ) ;
93+ for y in 0 ..5 {
94+ for x in 0 ..5 {
95+ a_new1. push ( xor_2 ( & a[ x + ( y * 5usize ) ] , & d[ x] ) ?) ;
96+ }
97+ }
98+
99+ // # ρ and π steps
100+ // B[y,2*x+3*y] = rot(A[x,y], r[x,y]), for (x,y) in (0…4,0…4)
101+ let mut b = a_new1. clone ( ) ;
102+ for y in 0 ..5 {
103+ for x in 0 ..5 {
104+ b[ y + ( ( ( ( 2 * x) + ( 3 * y) ) % 5 ) * 5usize ) ] =
105+ // a_new1[x + (y * 5usize)].rotate_left(ROTR[x + (y * 5usize)]);
106+ rotate_left ( & a_new1[ x + ( y * 5usize ) ] , ROTR [ x + ( y * 5usize ) ] ) ;
107+ }
108+ }
109+
110+ let mut a_new2 = Vec :: new ( ) ;
111+
112+ // # χ step
113+ // A[x,y] = B[x,y] xor ((not B[x+1,y]) and B[x+2,y]), for (x,y) in (0…4,0…4)
114+ for y in 0 ..5 {
115+ for x in 0 ..5 {
116+ a_new2. push ( xor_not_and (
117+ & b[ x + ( y * 5usize ) ] ,
118+ & b[ ( ( x + 1usize ) % 5usize ) + ( y * 5usize ) ] ,
119+ & b[ ( ( x + 2usize ) % 5usize ) + ( y * 5usize ) ] ,
120+ ) ?) ;
121+ }
122+ }
123+
124+ // // # ι step
125+ // // A[0,0] = A[0,0] xor RC
126+ let rc = UInt64 :: constant ( rc) ;
127+ a_new2[ 0 ] = a_new2[ 0 ] . clone ( ) . xor ( & rc) ?;
128+
129+ Ok ( a_new2)
130+ }
131+
132+ fn keccak_f_1600 < F : PrimeField > (
133+ // cs: &ConstraintSystemRef<F>,
134+ input : Vec < Boolean < F > > ,
135+ ) -> Result < Vec < Boolean < F > > , SynthesisError > {
136+
137+ assert_eq ! ( input. len( ) , 1600 ) ;
138+
139+ let mut a = input
140+ . chunks ( 64 )
141+ . map ( |e| UInt64 :: from_bits_le ( e) )
142+ . collect :: < Vec < _ > > ( ) ;
143+
144+ for i in 0 ..24 {
145+ // a = round_1600(cs, a, ROUND_CONSTANTS[i])?;
146+ a = round_1600 ( a, ROUND_CONSTANTS [ i] ) ?;
147+ }
148+
149+ let a_new = a. into_iter ( ) . flat_map ( |e| e. to_bits_le ( ) ) . collect ( ) ;
150+
151+ Ok ( a_new)
152+ }
153+
154+ pub fn keccak256 < F : PrimeField > (
155+ // cs: &ConstraintSystemRef<F>,
156+ input : & [ Boolean < F > ] ,
157+ ) -> Result < Vec < Boolean < F > > , SynthesisError > {
158+
159+ let block_size = 136 * 8 ; //136 bytes * 8 = 1088 bit
160+ let input_len = input. len ( ) ;
161+ let num_blocks = input_len / block_size + 1 ;
162+ let padded_len = num_blocks * block_size;
163+ let mut padded = vec ! [ Boolean :: constant( false ) ; padded_len] ;
164+ for i in 0 ..input. len ( ) {
165+ padded[ i] = input[ i] . clone ( ) ;
166+ }
167+
168+
169+ // # Padding
170+ // d = 2^|Mbits| + sum for i=0..|Mbits|-1 of 2^i*Mbits[i]
171+ // P = Mbytes || d || 0x00 || … || 0x00
172+ // P = P xor (0x00 || … || 0x00 || 0x80)
173+ //0x0100 ... 0080
174+ padded[ input_len] = Boolean :: constant ( true ) ;
175+ padded[ padded_len - 1 ] = Boolean :: constant ( true ) ;
176+
177+ // # Initialization
178+ // S[x,y] = 0, for (x,y) in (0…4,0…4)
179+
180+ // # Absorbing phase
181+ // for each block Pi in P
182+ // S[x,y] = S[x,y] xor Pi[x+5*y], for (x,y) such that x+5*y < r/w
183+ // S = Keccak-f[r+c](S)
184+ let mut m = vec ! [ Boolean :: constant( false ) ; 1600 ] ;
185+
186+ for i in 0 ..num_blocks {
187+ for j in 0 ..block_size {
188+ m[ j] = m[ j] . clone ( ) . xor ( & padded[ i * block_size + j] ) ?;
189+ }
190+ //m = keccak_f_1600(cs, m)?;
191+ m = keccak_f_1600 ( m) ?;
192+ }
193+
194+ // # Squeezing phase
195+ // Z = empty string
196+ let mut z = Vec :: new ( ) ;
197+
198+ // while output is requested
199+ // Z = Z || S[x,y], for (x,y) such that x+5*y < r/w
200+ // S = Keccak-f[r+c](S)
201+ for i in 0 ..256 {
202+ z. push ( m[ i] . clone ( ) ) ;
203+ }
204+
205+ return Ok ( z) ;
206+ }
207+
7208
8209pub trait KeccakHash : SimpleField {
9210 fn hash ( data : & [ <Self as SimpleField >:: ByteType ] ) -> Vec < <Self as SimpleField >:: ByteType > ;
@@ -19,6 +220,66 @@ impl KeccakHash for Fp {
19220
20221impl < F : PrimeField + SimpleField > KeccakHash for FpVar < F > {
21222 fn hash ( data : & [ <Self as SimpleField >:: ByteType ] ) -> Vec < <Self as SimpleField >:: ByteType > {
22- unimplemented ! ( )
223+ // convert input to boolean
224+ let input= data. iter ( )
225+ . flat_map ( |byte| byte. to_bits_le ( ) . unwrap ( ) )
226+ . collect :: < Vec < _ > > ( ) ;
227+
228+ let res = match keccak256 ( & input) {
229+ Ok ( res) => res,
230+ Err ( e) => {
231+ panic ! ( "keccak256 hash err:{}" , e) ;
232+ }
233+ } ;
234+
235+ //convert output to bytes
236+ let output = res
237+ . chunks ( 8 )
238+ . map ( UInt8 :: from_bits_le)
239+ . collect :: < Vec < _ > > ( ) ;
240+ output
23241 }
24242}
243+
244+
245+ #[ cfg( test) ]
246+ mod tests {
247+ use super :: * ;
248+ use swiftness_field:: StarkArkConvert ;
249+ use KeccakHash ;
250+ use ark_ff:: Field ;
251+ use ark_ff:: MontFp as Fp ;
252+ use swiftness_field:: Fp ;
253+ fn keccak_hash ( data : & [ u8 ] ) -> Vec < u8 > {
254+ let mut hasher = Keccak256 :: new ( ) ;
255+ hasher. update ( data) ;
256+ hasher. finalize ( ) . to_vec ( )
257+ }
258+
259+ #[ test]
260+ fn test_keccak_hash_fp ( ) {
261+ let input_len = 1024 ;
262+ let mut rng = thread_rng ( ) ;
263+ let input: Vec < u8 > = ( 0 ..input_len) . map ( |_| rng. gen ( ) ) . collect ( ) ;
264+ let real_bytes: Vec < u8 > = <Fp as KeccakHash >:: hash ( & input) ;
265+ let expected = keccak_hash ( & input) ;
266+ assert_eq ! ( real_bytes, expected) ;
267+
268+ }
269+ #[ test]
270+ fn test_keccak_hash_fp_var ( ) {
271+ let input_len = 1024 ;
272+ let mut rng = thread_rng ( ) ;
273+ let input: Vec < u8 > = ( 0 ..input_len) . map ( |_| rng. gen ( ) ) . collect ( ) ;
274+ //let input_fp = input.iter().map(|x| Fp::from(*x)).collect::<Vec<_>>();
275+ let cs = ConstraintSystem :: < Fp > :: new_ref ( ) ;
276+ let input_fp = UInt8 :: new_input_vec ( ark_relations:: ns!( cs, "input" ) , & input) . unwrap ( ) ;
277+ let real_bytes: Vec < UInt8 < Fp > > = <FpVar < Fp > as KeccakHash >:: hash ( & input_fp) ;
278+ let expected = keccak_hash ( & input) ;
279+ assert_eq ! ( real_bytes. len( ) , expected. len( ) ) ;
280+ for i in 0 ..real_bytes. len ( ) {
281+ assert_eq ! ( real_bytes[ i] . value( ) . unwrap( ) , expected[ i] ) ;
282+ }
283+ }
284+
285+ }
0 commit comments