Skip to content

Commit

Permalink
clean
Browse files Browse the repository at this point in the history
  • Loading branch information
thor314 committed Aug 16, 2024
1 parent 91090b6 commit ddef808
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 247 deletions.
6 changes: 2 additions & 4 deletions circuits/aes-gcm/gfmulx.circom
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ include "helper_functions.circom";
//
// spec:
// https://tools.ietf.org/html/rfc8452#appendix-A
//
// rust-crypto reference implementation: todo
template ghash_GFMULX() {
signal input in[128];
signal output out[128];
Expand All @@ -20,11 +18,11 @@ template ghash_GFMULX() {
v[0] <== 0;
for (var i = 1; i < 128; i++) { v[i] <== in[i-1]; }

// if MSB set, assign irreducible poly bits, otherwise zero
// irreducible_poly has 1s at positions 1, 2, 7, 127
signal irreducible_poly[128];
for (var i = 0; i < 128; i++) {
if (i==0 || i == 1 || i==6 || i==127) { // passes rust-crypto
// // if (i==7 || i==121 || i==126) { // passes ietf spec?
if (i==0 || i == 1 || i==6 || i==127) {
irreducible_poly[i] <== msb;
} else {
irreducible_poly[i] <== 0;
Expand Down
68 changes: 66 additions & 2 deletions circuits/test/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,72 @@
import { assert } from "chai";
import { Circomkit, WitnessTester } from "circomkit";
import 'mocha';
import "mocha";

export const circomkit = new Circomkit({
verbose: false,
verbose: false,
});

export { WitnessTester };

export function hexToBitArray(hex: string): number[] {
// Remove '0x' prefix if present and ensure lowercase
hex = hex.replace(/^0x/i, "").toLowerCase();

// Ensure even number of characters
if (hex.length % 2 !== 0) {
hex = "0" + hex;
}

return (
hex
// Split into pairs of characters
.match(/.{2}/g)!
.flatMap((pair) => {
const byte = parseInt(pair, 16);
// map byte to 8-bits. Apologies for the obtuse mapping;
// which cycles through the bits in byte and extracts them one by one.
return Array.from({ length: 8 }, (_, i) => (byte >> (7 - i)) & 1);
})
);
}

export function bitArrayToHex(bits: number[]): string {
// console.log(bits);
if (bits.length % 8 !== 0) {
throw new Error("Input length must be a multiple of 8 bits");
}

return bits
.reduce((acc, bit, index) => {
const byteIndex = Math.floor(index / 8);
const bitPosition = 7 - (index % 8);
acc[byteIndex] = (acc[byteIndex] || 0) | (bit << bitPosition);
return acc;
}, new Array(bits.length / 8).fill(0))
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
}

it("tests hexToBitArray", async () => {
let hex = "0F";
let expectedBits = [0, 0, 0, 0, 1, 1, 1, 1];
let result = hexToBitArray(hex);
assert.deepEqual(result, expectedBits);

hex = "1248";
expectedBits = [0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0];
result = hexToBitArray(hex);
assert.deepEqual(result, expectedBits);
});

it("tests bitArrayToHexString", async () => {
let bits = [0, 0, 0, 0, 1, 1, 1, 1];
let expectedHex = "0f";
let result = bitArrayToHex(bits);
assert.equal(result, expectedHex);

bits = [1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1];
expectedHex = "8b09";
result = bitArrayToHex(bits);
assert.equal(result, expectedHex);
});
178 changes: 3 additions & 175 deletions circuits/test/gfmulx/ghash_mulx.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import chai, { assert, expect } from "chai";
import { WitnessTester } from "circomkit";
import { circomkit } from "../common";
import { bitArrayToHex, circomkit, hexToBitArray } from "../common";

// Disable truncation of arrays in error messages
chai.config.truncateThreshold = 0;
Expand Down Expand Up @@ -148,7 +148,7 @@ describe("ghash_GFMulX", () => {
const result = bitArrayToHex(
(_res.out as (number | bigint)[]).map((bit) => Number(bit))
);
console.log("expect: ", expect, "\nresult: ", result);
// console.log("expect: ", expect, "\nresult: ", result);
assert.equal(expect, result);
bits = hexToBitArray(result);
}
Expand All @@ -162,180 +162,8 @@ describe("ghash_GFMulX", () => {
const result = bitArrayToHex(
(_res.out as (number | bigint)[]).map((bit) => Number(bit))
);
console.log("expect: ", expect, "\nresult: ", result);
// console.log("expect: ", expect, "\nresult: ", result);
assert.equal(expect, result);
});
});
});

function hexToBitArray(hex: string): number[] {
// Remove '0x' prefix if present and ensure lowercase
hex = hex.replace(/^0x/i, "").toLowerCase();

// Ensure even number of characters
if (hex.length % 2 !== 0) {
hex = "0" + hex;
}

return (
hex
// Split into pairs of characters
.match(/.{2}/g)!
.flatMap((pair) => {
const byte = parseInt(pair, 16);
// map byte to 8-bits. Apologies for the obtuse mapping;
// which cycles through the bits in byte and extracts them one by one.
return Array.from({ length: 8 }, (_, i) => (byte >> (7 - i)) & 1);
})
);
}

function bitArrayToHex(bits: number[]): string {
// console.log(bits);
if (bits.length % 8 !== 0) {
throw new Error("Input length must be a multiple of 8 bits");
}

return bits
.reduce((acc, bit, index) => {
const byteIndex = Math.floor(index / 8);
const bitPosition = 7 - (index % 8);
acc[byteIndex] = (acc[byteIndex] || 0) | (bit << bitPosition);
return acc;
}, new Array(bits.length / 8).fill(0))
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
}

describe("LeftShiftLE", () => {
const shift_1 = 1;
const shift_2 = 2;
let circuit: WitnessTester<["in"], ["out"]>;

describe("leftshiftLE", () => {
before(async () => {
circuit = await circomkit.WitnessTester(`LeftShiftLE`, {
file: "aes-gcm/gfmulx",
template: "LeftShiftLE",
params: [shift_1],
});
});

it("tests leftshiftLE", async () => {
let bits = [1].concat(Array(127).fill(0));
let expect = Array(15).fill(0).concat([1]).concat(Array(112).fill(0));
let _res = await circuit.compute({ in: bits }, ["out"]);
let result = (_res.out as (number | bigint)[]).map((bit) => Number(bit));
assert.deepEqual(result, expect);

bits = [0, 1].concat(Array(126).fill(0));
expect = [1].concat(Array(127).fill(0));
_res = await circuit.compute({ in: bits }, ["out"]);
result = (_res.out as (number | bigint)[]).map((bit) => Number(bit));
assert.deepEqual(result, expect);
});
});

describe("leftshiftLE shift 2", () => {
before(async () => {
circuit = await circomkit.WitnessTester(`LeftShiftLE`, {
file: "aes-gcm/gfmulx",
template: "LeftShiftLE",
params: [shift_2],
});
});

it("tests leftshiftLE", async () => {
let bits = [1].concat(Array(127).fill(0));
let expect = Array(14).fill(0).concat([1]).concat(Array(113).fill(0));
let _res = await circuit.compute({ in: bits }, ["out"]);
let result = (_res.out as (number | bigint)[]).map((bit) => Number(bit));
assert.deepEqual(result, expect);
});
});
});

// // ghash irreducible polynomial: x^128 = x^7 + x^2 + x + 1
// const ghashIrreduciblePolynomial: number[] = Array(120)
// .fill(0)
// .concat([1, 0, 0, 0, 0, 1, 1, 1]);

// describe("ghash_GFMulX", () => {
// let circuit: WitnessTester<["in"], ["out"]>;

// describe("ghash GF Mul X test", () => {
// before(async () => {
// circuit = await circomkit.WitnessTester(`gfmulx`, {
// file: "aes-gcm/gfmulx",
// template: "ghash_GFMULX",
// });
// console.log("#constraints:", await circuit.getConstraintCount());
// });

// it("send 1000... to the irreducible polynomial", async () => {
// const test = [1].concat(Array(127).fill(0));
// await circuit.expectPass(
// { in: test },
// { out: ghashIrreduciblePolynomial }
// );
// });

// // ref: https://datatracker.ietf.org/doc/html/rfc8452#appendix-A
// // todo
// it("compute IETF test 1: expect 2", async () => {
// let bits = hexToBitArray("01000000000000000000000000000000");
// let expected = hexToBitArray("00800000000000000000000000000000");
// // let expected = [0,0,8].concat(Array(29).fill(0))
// // console.log(bits);
// // console.log(expected);
// await circuit.expectPass({ in: bits }, { out: expected });
// });

// // ref: https://datatracker.ietf.org/doc/html/rfc8452#appendix-A
// it("compute IETF test 2", async () => {
// let bits = hexToBitArray("9c98c04df9387ded828175a92ba652d8");
// let expected_output = hexToBitArray("4e4c6026fc9c3ef6c140bad495d3296c");
// // console.log(bits);
// // console.log(expected_output);
// await circuit.expectPass({ in: bits }, { out: expected_output });
// });

// it("tests hexToBitArray", async () => {
// let hex = "0F";
// let expectedBits = [0, 0, 0, 0, 1, 1, 1, 1];
// let result = hexToBitArray(hex);
// result.forEach((bit, index) => {
// expect(bit).equals(expectedBits[index]);
// });

// hex = "1248";
// expectedBits = [0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0];
// result = hexToBitArray(hex);
// result.forEach((bit, index) => {
// expect(bit).equals(expectedBits[index]);
// });
// });
// });
// });

// function hexToBitArray(hex: string): number[] {
// // Remove '0x' prefix if present and ensure lowercase
// hex = hex.replace(/^0x/i, "").toLowerCase();

// // Ensure even number of characters
// if (hex.length % 2 !== 0) {
// hex = "0" + hex;
// }

// return (
// hex
// // Split into pairs of characters
// .match(/.{2}/g)!
// .flatMap((pair) => {
// const byte = parseInt(pair, 16);
// // map byte to 8-bits. Apologies for the obtuse mapping;
// // which cycles through the bits in byte and extracts them one by one.
// return Array.from({ length: 8 }, (_, i) => (byte >> (7 - i)) & 1);
// })
// );
// }
69 changes: 3 additions & 66 deletions circuits/test/gfmulx/polyval_mulx.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import chai, { assert, expect } from "chai";
import { WitnessTester } from "circomkit";
import { circomkit } from "../common";
import { bitArrayToHex, circomkit, hexToBitArray } from "../common";

// Disable truncation of arrays in error messages
chai.config.truncateThreshold = 0;
Expand Down Expand Up @@ -156,7 +156,7 @@ describe("polyval_GFMulX", () => {
const result = bitArrayToHex(
(_res.out as (number | bigint)[]).map((bit) => Number(bit))
);
console.log("expect: ", expect, "\nresult: ", result);
// console.log("expect: ", expect, "\nresult: ", result);
assert.equal(expect, result);
bits = hexToBitArray(result);
}
Expand All @@ -170,75 +170,12 @@ describe("polyval_GFMulX", () => {
const result = bitArrayToHex(
(_res.out as (number | bigint)[]).map((bit) => Number(bit))
);
console.log("expect: ", expect, "\nresult: ", result);
// console.log("expect: ", expect, "\nresult: ", result);
assert.equal(expect, result);
});

it("tests hexToBitArray", async () => {
let hex = "0F";
let expectedBits = [0, 0, 0, 0, 1, 1, 1, 1];
let result = hexToBitArray(hex);
assert.deepEqual(result, expectedBits);

hex = "1248";
expectedBits = [0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0];
result = hexToBitArray(hex);
assert.deepEqual(result, expectedBits);
});

it("tests bitArrayToHexString", async () => {
let bits = [0, 0, 0, 0, 1, 1, 1, 1];
let expectedHex = "0f";
let result = bitArrayToHex(bits);
assert.equal(result, expectedHex);

bits = [1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1];
expectedHex = "8b09";
result = bitArrayToHex(bits);
assert.equal(result, expectedHex);
});
});
});

function hexToBitArray(hex: string): number[] {
// Remove '0x' prefix if present and ensure lowercase
hex = hex.replace(/^0x/i, "").toLowerCase();

// Ensure even number of characters
if (hex.length % 2 !== 0) {
hex = "0" + hex;
}

return (
hex
// Split into pairs of characters
.match(/.{2}/g)!
.flatMap((pair) => {
const byte = parseInt(pair, 16);
// map byte to 8-bits. Apologies for the obtuse mapping;
// which cycles through the bits in byte and extracts them one by one.
return Array.from({ length: 8 }, (_, i) => (byte >> (7 - i)) & 1);
})
);
}

function bitArrayToHex(bits: number[]): string {
// console.log(bits);
if (bits.length % 8 !== 0) {
throw new Error("Input length must be a multiple of 8 bits");
}

return bits
.reduce((acc, bit, index) => {
const byteIndex = Math.floor(index / 8);
const bitPosition = 7 - (index % 8);
acc[byteIndex] = (acc[byteIndex] || 0) | (bit << bitPosition);
return acc;
}, new Array(bits.length / 8).fill(0))
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
}

describe("LeftShiftLE", () => {
const shift_1 = 1;
const shift_2 = 2;
Expand Down

0 comments on commit ddef808

Please sign in to comment.