11import { WitnessTester } from "circomkit" ;
2- import { circomkit , toUint32Array , uintArray32ToBits } from "../common" ;
2+ import { circomkit , toByte , toUint32Array , uintArray32ToBits } from "../common" ;
33import { DataHasher } from "../common/poseidon" ;
44import { assert } from "chai" ;
55
66
77describe ( "chacha20-nivc" , ( ) => {
8+ let circuit : WitnessTester < [ "key" , "nonce" , "counter" , "plainText" , "cipherText" , "step_in" ] , [ "step_out" ] > ;
89 describe ( "16 block test" , ( ) => {
9- let circuit : WitnessTester < [ "key" , "nonce" , "counter" , "plainText" , "cipherText" , "step_in" ] , [ "step_out" ] > ;
1010 it ( "should perform encryption" , async ( ) => {
1111 circuit = await circomkit . WitnessTester ( `ChaCha20` , {
1212 file : "chacha20/nivc/chacha20_nivc" ,
1313 template : "ChaCha20_NIVC" ,
14- params : [ 16 ] // number of 32-bit words in the key, 32 * 16 = 512 bits
14+ params : [ 64 ] // number of bytes for plaintext
1515 } ) ;
1616 // Test case from RCF https://www.rfc-editor.org/rfc/rfc7539.html#section-2.4.2
17- // the input encoding here is not the most intuitive. inputs are serialized as little endian.
17+ // the input encoding here is not the most intuitive. inputs are serialized as little endian.
1818 // i.e. "e4e7f110" is serialized as "10 f1 e7 e4". So the way i am reading in inputs is
19- // to ensure that every 32 bit word is byte reversed before being turned into bits.
19+ // to ensure that every 32 bit word is byte reversed before being turned into bits.
2020 // i think this should be easy when we compute witness in rust.
2121 let keyBytes = [
22- 0x00 , 0x01 , 0x02 , 0x03 ,
23- 0x04 , 0x05 , 0x06 , 0x07 ,
24- 0x08 , 0x09 , 0x0a , 0x0b ,
25- 0x0c , 0x0d , 0x0e , 0x0f ,
26- 0x10 , 0x11 , 0x12 , 0x13 ,
27- 0x14 , 0x15 , 0x16 , 0x17 ,
28- 0x18 , 0x19 , 0x1a , 0x1b ,
29- 0x1c , 0x1d , 0x1e , 0x1f
30- ] ;
22+ 0x00 , 0x01 , 0x02 , 0x03 ,
23+ 0x04 , 0x05 , 0x06 , 0x07 ,
24+ 0x08 , 0x09 , 0x0a , 0x0b ,
25+ 0x0c , 0x0d , 0x0e , 0x0f ,
26+ 0x10 , 0x11 , 0x12 , 0x13 ,
27+ 0x14 , 0x15 , 0x16 , 0x17 ,
28+ 0x18 , 0x19 , 0x1a , 0x1b ,
29+ 0x1c , 0x1d , 0x1e , 0x1f
30+ ] ;
3131
3232 let nonceBytes =
3333 [
3434 0x00 , 0x00 , 0x00 , 0x00 ,
3535 0x00 , 0x00 , 0x00 , 0x4a ,
3636 0x00 , 0x00 , 0x00 , 0x00
3737 ] ;
38- let plaintextBytes =
38+ let plaintextBytes =
3939 [
4040 0x4c , 0x61 , 0x64 , 0x69 , 0x65 , 0x73 , 0x20 , 0x61 , 0x6e , 0x64 , 0x20 , 0x47 , 0x65 , 0x6e , 0x74 , 0x6c ,
4141 0x65 , 0x6d , 0x65 , 0x6e , 0x20 , 0x6f , 0x66 , 0x20 , 0x74 , 0x68 , 0x65 , 0x20 , 0x63 , 0x6c , 0x61 , 0x73 ,
@@ -48,21 +48,75 @@ describe("chacha20-nivc", () => {
4848 0xe9 , 0x7e , 0x7a , 0xec , 0x1d , 0x43 , 0x60 , 0xc2 , 0x0a , 0x27 , 0xaf , 0xcc , 0xfd , 0x9f , 0xae , 0x0b ,
4949 0xf9 , 0x1b , 0x65 , 0xc5 , 0x52 , 0x47 , 0x33 , 0xab , 0x8f , 0x59 , 0x3d , 0xab , 0xcd , 0x62 , 0xb3 , 0x57 ,
5050 0x16 , 0x39 , 0xd6 , 0x24 , 0xe6 , 0x51 , 0x52 , 0xab , 0x8f , 0x53 , 0x0c , 0x35 , 0x9f , 0x08 , 0x61 , 0xd8
51- ] ;
52- const ciphertextBits = toInput ( Buffer . from ( ciphertextBytes ) )
53- const plaintextBits = toInput ( Buffer . from ( plaintextBytes ) )
54- const counterBits = uintArray32ToBits ( [ 1 ] ) [ 0 ]
55- let w = await circuit . compute ( {
56- key : toInput ( Buffer . from ( keyBytes ) ) ,
57- nonce : toInput ( Buffer . from ( nonceBytes ) ) ,
58- counter : counterBits ,
59- cipherText : ciphertextBits ,
60- plainText : plaintextBits ,
51+ ] ;
52+ const counterBits = uintArray32ToBits ( [ 1 ] ) [ 0 ]
53+ let w = await circuit . compute ( {
54+ key : toInput ( Buffer . from ( keyBytes ) ) ,
55+ nonce : toInput ( Buffer . from ( nonceBytes ) ) ,
56+ counter : counterBits ,
57+ cipherText : ciphertextBytes ,
58+ plainText : plaintextBytes ,
6159 step_in : 0
62- } , ( [ "step_out" ] ) ) ;
60+ } , ( [ "step_out" ] ) ) ;
6361 assert . deepEqual ( w . step_out , DataHasher ( plaintextBytes ) ) ;
6462 } ) ;
6563 } ) ;
64+
65+ describe ( "padded plaintext" , ( ) => {
66+ it ( "should perform encryption" , async ( ) => {
67+ circuit = await circomkit . WitnessTester ( `ChaCha20` , {
68+ file : "chacha20/nivc/chacha20_nivc" ,
69+ template : "ChaCha20_NIVC" ,
70+ params : [ 128 ] // number of bytes in plaintext
71+ } ) ;
72+ // Test case from RCF https://www.rfc-editor.org/rfc/rfc7539.html#section-2.4.2
73+ // the input encoding here is not the most intuitive. inputs are serialized as little endian.
74+ // i.e. "e4e7f110" is serialized as "10 f1 e7 e4". So the way i am reading in inputs is
75+ // to ensure that every 32 bit word is byte reversed before being turned into bits.
76+ // i think this should be easy when we compute witness in rust.
77+ let keyBytes = [
78+ 0x00 , 0x01 , 0x02 , 0x03 ,
79+ 0x04 , 0x05 , 0x06 , 0x07 ,
80+ 0x08 , 0x09 , 0x0a , 0x0b ,
81+ 0x0c , 0x0d , 0x0e , 0x0f ,
82+ 0x10 , 0x11 , 0x12 , 0x13 ,
83+ 0x14 , 0x15 , 0x16 , 0x17 ,
84+ 0x18 , 0x19 , 0x1a , 0x1b ,
85+ 0x1c , 0x1d , 0x1e , 0x1f
86+ ] ;
87+
88+ let nonceBytes =
89+ [
90+ 0x00 , 0x00 , 0x00 , 0x00 ,
91+ 0x00 , 0x00 , 0x00 , 0x4a ,
92+ 0x00 , 0x00 , 0x00 , 0x00
93+ ] ;
94+ let plaintextBytes =
95+ toByte ( "Ladies and Gentlemen of the class of '99: If I could offer you only one tip " ) ;
96+
97+ let ciphertextBytes =
98+ [
99+ 0x6e , 0x2e , 0x35 , 0x9a , 0x25 , 0x68 , 0xf9 , 0x80 , 0x41 , 0xba , 0x07 , 0x28 , 0xdd , 0x0d , 0x69 , 0x81 ,
100+ 0xe9 , 0x7e , 0x7a , 0xec , 0x1d , 0x43 , 0x60 , 0xc2 , 0x0a , 0x27 , 0xaf , 0xcc , 0xfd , 0x9f , 0xae , 0x0b ,
101+ 0xf9 , 0x1b , 0x65 , 0xc5 , 0x52 , 0x47 , 0x33 , 0xab , 0x8f , 0x59 , 0x3d , 0xab , 0xcd , 0x62 , 0xb3 , 0x57 ,
102+ 0x16 , 0x39 , 0xd6 , 0x24 , 0xe6 , 0x51 , 0x52 , 0xab , 0x8f , 0x53 , 0x0c , 0x35 , 0x9f , 0x08 , 0x61 , 0xd8 ,
103+ 0x07 , 0xca , 0x0d , 0xbf , 0x50 , 0x0d , 0x6a , 0x61 , 0x56 , 0xa3 , 0x8e , 0x08
104+ ] ;
105+ let totalLength = 128 ;
106+ let paddedPlaintextBytes = plaintextBytes . concat ( Array ( totalLength - plaintextBytes . length ) . fill ( 0 ) ) ;
107+ let paddedCiphertextBytes = ciphertextBytes . concat ( Array ( totalLength - ciphertextBytes . length ) . fill ( 0 ) ) ;
108+ const counterBits = uintArray32ToBits ( [ 1 ] ) [ 0 ]
109+ let w = await circuit . compute ( {
110+ key : toInput ( Buffer . from ( keyBytes ) ) ,
111+ nonce : toInput ( Buffer . from ( nonceBytes ) ) ,
112+ counter : counterBits ,
113+ cipherText : paddedCiphertextBytes ,
114+ plainText : paddedPlaintextBytes ,
115+ step_in : 0
116+ } , ( [ "step_out" ] ) ) ;
117+ assert . deepEqual ( w . step_out , DataHasher ( paddedPlaintextBytes ) ) ;
118+ } ) ;
119+ } ) ;
66120} ) ;
67121
68122
0 commit comments