Skip to content

Commit 8ba2c51

Browse files
author
AztecBot
committed
Merge branch 'next' into merge-train/spartan
2 parents c091806 + 5d69881 commit 8ba2c51

3 files changed

Lines changed: 200 additions & 0 deletions

File tree

noir-projects/noir-contracts/contracts/test/avm_gadgets_test_contract/src/main.nr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ contract AvmGadgetsTest {
99
keccak256::keccak256(data, data.len())
1010
}
1111

12+
// 300 bytes exceeds the keccak256 rate (136 bytes), triggering multi-block permutation.
13+
#[external("public")]
14+
fn keccak_hash_300(data: [u8; 300]) -> [u8; 32] {
15+
keccak256::keccak256(data, data.len())
16+
}
17+
1218
#[external("public")]
1319
fn keccak_hash_1400(data: [u8; 1400]) -> [u8; 32] {
1420
keccak256::keccak256(data, data.len())

yarn-project/bb-prover/src/avm_proving_tests/avm_proven_gadgets.test.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,111 @@ describe.skip('AVM proven gadgets test', () => {
102102
expect(result.revertCode.isOK()).toBe(true);
103103
}, 300_000);
104104
});
105+
106+
describe('AVM proven gadgets test: test vectors', () => {
107+
let tester: AvmProvingTester;
108+
let worldStateService: NativeWorldStateService;
109+
110+
const sender = AztecAddress.fromNumber(42);
111+
let avmGadgetsTestContract: ContractInstanceWithAddress;
112+
113+
beforeEach(async () => {
114+
worldStateService = await NativeWorldStateService.tmp();
115+
tester = await AvmProvingTester.new(worldStateService, /*checkCircuitOnly=*/ false, /*globals=*/ defaultGlobals());
116+
avmGadgetsTestContract = await tester.registerAndDeployContract(
117+
/*constructorArgs=*/ [],
118+
sender,
119+
/*contractArtifact=*/ AvmGadgetsTestContractArtifact,
120+
);
121+
});
122+
123+
afterEach(async () => {
124+
await worldStateService.close();
125+
});
126+
127+
it('keccak_hash_test_vector', async () => {
128+
// keccak256([0x00, 0x01, ..., 0x09]) = f0ae86a6257e615bce8b0fe73794934deda00c13d58f80b466a9354e306c9eb0
129+
const input = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
130+
const result = await tester.executeTxWithLabel(
131+
/*txLabel=*/ 'AvmGadgetsTest/keccak_hash',
132+
/*sender=*/ sender,
133+
/*setupCalls=*/ [],
134+
/*appCalls=*/ [
135+
{
136+
address: avmGadgetsTestContract.address,
137+
fnName: 'keccak_hash',
138+
args: [input],
139+
},
140+
],
141+
);
142+
expect(result.revertCode.isOK()).toBe(true);
143+
const outputBytes = result.getAppLogicReturnValues()?.[0]?.values?.map(fr => Number(fr.toBigInt()));
144+
const expected = [...Buffer.from('f0ae86a6257e615bce8b0fe73794934deda00c13d58f80b466a9354e306c9eb0', 'hex')];
145+
expect(outputBytes).toEqual(expected);
146+
}, 180_000);
147+
148+
it('keccak_hash_test_vector_300bytes', async () => {
149+
// 300 bytes exceeds the keccak256 rate (136 bytes), triggering multi-block permutation.
150+
// keccak256([0x00, 0x01, ..., 0x2b, 0x00, 0x01, ..., 0x2b, ...]) for 300 bytes
151+
const input = Array.from({ length: 300 }, (_, i) => i % 256);
152+
const result = await tester.executeTxWithLabel(
153+
/*txLabel=*/ 'AvmGadgetsTest/keccak_hash_300',
154+
/*sender=*/ sender,
155+
/*setupCalls=*/ [],
156+
/*appCalls=*/ [
157+
{
158+
address: avmGadgetsTestContract.address,
159+
fnName: 'keccak_hash_300',
160+
args: [input],
161+
},
162+
],
163+
);
164+
expect(result.revertCode.isOK()).toBe(true);
165+
const outputBytes = result.getAppLogicReturnValues()?.[0]?.values?.map(fr => Number(fr.toBigInt()));
166+
const expected = [...Buffer.from('a679e749a6af300c36e7ff2255d220864eab27b382f9cfdc5aa4d13563ba36ff', 'hex')];
167+
expect(outputBytes).toEqual(expected);
168+
}, 180_000);
169+
170+
it('sha256_hash_test_vector', async () => {
171+
// sha256([0x00, 0x01, ..., 0x09]) = 1f825aa2f0020ef7cf91dfa30da4668d791c5d4824fc8e41354b89ec05795ab3
172+
const input = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
173+
const result = await tester.executeTxWithLabel(
174+
/*txLabel=*/ 'AvmGadgetsTest/sha256_hash_10',
175+
/*sender=*/ sender,
176+
/*setupCalls=*/ [],
177+
/*appCalls=*/ [
178+
{
179+
address: avmGadgetsTestContract.address,
180+
fnName: 'sha256_hash_10',
181+
args: [input],
182+
},
183+
],
184+
);
185+
expect(result.revertCode.isOK()).toBe(true);
186+
const outputBytes = result.getAppLogicReturnValues()?.[0]?.values?.map(fr => Number(fr.toBigInt()));
187+
const expected = [...Buffer.from('1f825aa2f0020ef7cf91dfa30da4668d791c5d4824fc8e41354b89ec05795ab3', 'hex')];
188+
expect(outputBytes).toEqual(expected);
189+
}, 180_000);
190+
191+
it('sha256_hash_test_vector_255bytes', async () => {
192+
// 255 bytes exceeds the sha256 block size (64 bytes), triggering multi-block compression.
193+
// sha256([0x00, 0x01, ..., 0xfe]) = 3f8591112c6bbe5c963965954e293108b7208ed2af893e500d859368c654eabe
194+
const input = Array.from({ length: 255 }, (_, i) => i);
195+
const result = await tester.executeTxWithLabel(
196+
/*txLabel=*/ 'AvmGadgetsTest/sha256_hash_255',
197+
/*sender=*/ sender,
198+
/*setupCalls=*/ [],
199+
/*appCalls=*/ [
200+
{
201+
address: avmGadgetsTestContract.address,
202+
fnName: 'sha256_hash_255',
203+
args: [input],
204+
},
205+
],
206+
);
207+
expect(result.revertCode.isOK()).toBe(true);
208+
const outputBytes = result.getAppLogicReturnValues()?.[0]?.values?.map(fr => Number(fr.toBigInt()));
209+
const expected = [...Buffer.from('3f8591112c6bbe5c963965954e293108b7208ed2af893e500d859368c654eabe', 'hex')];
210+
expect(outputBytes).toEqual(expected);
211+
}, 180_000);
212+
});

yarn-project/simulator/src/public/public_tx_simulator/apps_tests/avm_gadgets.test.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,49 @@ describe('Public TX simulator apps tests: gadgets', () => {
5858
});
5959
});
6060

61+
it('sha256_hash_test_vector', async () => {
62+
// sha256([0x00, 0x01, ..., 0x09]) = 1f825aa2f0020ef7cf91dfa30da4668d791c5d4824fc8e41354b89ec05795ab3
63+
const input = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
64+
const result = await tester.executeTxWithLabel(
65+
/*txLabel=*/ 'AvmGadgetsTest/sha256_hash_10',
66+
/*sender=*/ deployer,
67+
/*setupCalls=*/ [],
68+
/*appCalls=*/ [
69+
{
70+
address: avmGadgetsTestContract.address,
71+
fnName: 'sha256_hash_10',
72+
args: [input],
73+
},
74+
],
75+
);
76+
expect(result.revertCode.isOK()).toBe(true);
77+
const outputBytes = result.getAppLogicReturnValues()?.[0]?.values?.map(fr => Number(fr.toBigInt()));
78+
const expected = [...Buffer.from('1f825aa2f0020ef7cf91dfa30da4668d791c5d4824fc8e41354b89ec05795ab3', 'hex')];
79+
expect(outputBytes).toEqual(expected);
80+
});
81+
82+
it('sha256_hash_test_vector_255bytes', async () => {
83+
// 255 bytes exceeds the sha256 block size (64 bytes), triggering multi-block compression.
84+
// sha256([0x00, 0x01, ..., 0xfe]) = 3f8591112c6bbe5c963965954e293108b7208ed2af893e500d859368c654eabe
85+
const input = Array.from({ length: 255 }, (_, i) => i);
86+
const result = await tester.executeTxWithLabel(
87+
/*txLabel=*/ 'AvmGadgetsTest/sha256_hash_255',
88+
/*sender=*/ deployer,
89+
/*setupCalls=*/ [],
90+
/*appCalls=*/ [
91+
{
92+
address: avmGadgetsTestContract.address,
93+
fnName: 'sha256_hash_255',
94+
args: [input],
95+
},
96+
],
97+
);
98+
expect(result.revertCode.isOK()).toBe(true);
99+
const outputBytes = result.getAppLogicReturnValues()?.[0]?.values?.map(fr => Number(fr.toBigInt()));
100+
const expected = [...Buffer.from('3f8591112c6bbe5c963965954e293108b7208ed2af893e500d859368c654eabe', 'hex')];
101+
expect(outputBytes).toEqual(expected);
102+
});
103+
61104
it('keccak_hash', async () => {
62105
const result = await tester.executeTxWithLabel(
63106
/*txLabel=*/ 'AvmGadgetsTest/keccak_hash',
@@ -74,6 +117,49 @@ describe('Public TX simulator apps tests: gadgets', () => {
74117
expect(result.revertCode.isOK()).toBe(true);
75118
});
76119

120+
it('keccak_hash_test_vector', async () => {
121+
// keccak256([0x00, 0x01, ..., 0x09]) = f0ae86a6257e615bce8b0fe73794934deda00c13d58f80b466a9354e306c9eb0
122+
const input = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
123+
const result = await tester.executeTxWithLabel(
124+
/*txLabel=*/ 'AvmGadgetsTest/keccak_hash',
125+
/*sender=*/ deployer,
126+
/*setupCalls=*/ [],
127+
/*appCalls=*/ [
128+
{
129+
address: avmGadgetsTestContract.address,
130+
fnName: 'keccak_hash',
131+
args: [input],
132+
},
133+
],
134+
);
135+
expect(result.revertCode.isOK()).toBe(true);
136+
const outputBytes = result.getAppLogicReturnValues()?.[0]?.values?.map(fr => Number(fr.toBigInt()));
137+
const expected = [...Buffer.from('f0ae86a6257e615bce8b0fe73794934deda00c13d58f80b466a9354e306c9eb0', 'hex')];
138+
expect(outputBytes).toEqual(expected);
139+
});
140+
141+
it('keccak_hash_test_vector_300bytes', async () => {
142+
// 300 bytes exceeds the keccak256 rate (136 bytes), triggering multi-block permutation.
143+
// keccak256([0x00, 0x01, ..., 0x2b, 0x00, 0x01, ..., 0x2b, ...]) for 300 bytes
144+
const input = Array.from({ length: 300 }, (_, i) => i % 256);
145+
const result = await tester.executeTxWithLabel(
146+
/*txLabel=*/ 'AvmGadgetsTest/keccak_hash_300',
147+
/*sender=*/ deployer,
148+
/*setupCalls=*/ [],
149+
/*appCalls=*/ [
150+
{
151+
address: avmGadgetsTestContract.address,
152+
fnName: 'keccak_hash_300',
153+
args: [input],
154+
},
155+
],
156+
);
157+
expect(result.revertCode.isOK()).toBe(true);
158+
const outputBytes = result.getAppLogicReturnValues()?.[0]?.values?.map(fr => Number(fr.toBigInt()));
159+
const expected = [...Buffer.from('a679e749a6af300c36e7ff2255d220864eab27b382f9cfdc5aa4d13563ba36ff', 'hex')];
160+
expect(outputBytes).toEqual(expected);
161+
});
162+
77163
it('keccak_hash_1400', async () => {
78164
const result = await tester.executeTxWithLabel(
79165
/*txLabel=*/ 'AvmGadgetsTest/keccak_hash_1400',

0 commit comments

Comments
 (0)