pow_sha256 serializes the phrase on which the proof is to be computed

using the bincode crate, which uses UTF-8 under the hood and also
prefixes the length of the string in big endian.

This patch introduces changes to implement the same
This commit is contained in:
Aravinth Manivannan 2021-12-08 13:43:24 +05:30
parent 76ff717acf
commit 9ea8676d24
Signed by: realaravinth
GPG key ID: AD9F0F08E855ED88
3 changed files with 49 additions and 17 deletions

View file

@ -2,7 +2,6 @@
* For a detailed explanation regarding each configuration property and type check, visit: * For a detailed explanation regarding each configuration property and type check, visit:
* https://jestjs.io/docs/en/configuration.html * https://jestjs.io/docs/en/configuration.html
*/ */
export default { export default {
// All imported modules in your tests should be mocked automatically // All imported modules in your tests should be mocked automatically
// automock: false, // automock: false,
@ -16,6 +15,8 @@ export default {
// Automatically clear mock calls and instances between every test // Automatically clear mock calls and instances between every test
clearMocks: true, clearMocks: true,
testTimeout: 300000,
// Indicates whether the coverage information should be collected while executing the test // Indicates whether the coverage information should be collected while executing the test
collectCoverage: true, collectCoverage: true,
@ -31,6 +32,7 @@ export default {
"setupTests.ts", "setupTests.ts",
"setUpTests.ts", "setUpTests.ts",
"jest.setup.ts", "jest.setup.ts",
"test-data.ts",
], ],
// Indicates which provider should be used to instrument code for coverage // Indicates which provider should be used to instrument code for coverage

View file

@ -10,6 +10,29 @@
*/ */
const U128_MAX = 340282366920938463463374607431768211455n; const U128_MAX = 340282366920938463463374607431768211455n;
const encoder = new TextEncoder();
const decoder = new TextDecoder("utf-8");
const length_metadata = (len: number): number[] => {
return [
(len & 0x00000000000000ff) >> 0,
(len & 0x000000000000ff00) >> 8,
(len & 0x0000000000ff0000) >> 16,
(len & 0x00000000ff000000) >> 24,
(len & 0x000000ff00000000) >> 32,
(len & 0x0000ff000000000) >> 48,
(len & 0x00ff00000000000) >> 56,
Number((BigInt(len) & 0xff0000000000000n) >> BigInt(64)),
];
};
const serialize = (message: string): Uint8Array => {
const len_encoded = length_metadata(message.length);
const msgUint8 = new Uint8Array(
len_encoded.concat(Array.from(encoder.encode(message)))
);
return msgUint8;
};
/** /**
* Compute SHA-256 digest of a string * Compute SHA-256 digest of a string
@ -17,8 +40,8 @@ const U128_MAX = 340282366920938463463374607431768211455n;
* @returns {number[]} - byte array of the hash * @returns {number[]} - byte array of the hash
**/ **/
export const digest = async (message: string): Promise<number[]> => { export const digest = async (message: string): Promise<number[]> => {
const msgUint8 = new TextEncoder().encode(message); const msgUint8 = encoder.encode(message);
msgUint8;
const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8); const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8);
const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray; return hashArray;
@ -65,11 +88,11 @@ export const generate_work = async (
phrase: string, phrase: string,
difficulty: number difficulty: number
): Promise<WasmWork> => { ): Promise<WasmWork> => {
const base = salt + phrase; const serialized_phrase = decoder.decode(serialize(phrase));
const base = salt + serialized_phrase;
let nonce = 0; let nonce = 0;
let result: BigInt = BigInt(0); let result: BigInt = BigInt(0);
const difficulty_new = U128_MAX - (U128_MAX / BigInt(difficulty)); const difficulty_new = U128_MAX - U128_MAX / BigInt(difficulty);
console.log(difficulty_new==340275561273600044694105339939619576091n);
while (result < difficulty_new) { while (result < difficulty_new) {
nonce += 1; nonce += 1;
const hash = await digest(base + nonce.toString()); const hash = await digest(base + nonce.toString());

View file

@ -3,20 +3,27 @@ import { DATA, DIFFICULTY, SALT } from "./test-data";
("use strict"); ("use strict");
it("Everything works", async () => { test("Proof generation works", async () => {
for (let i = 0; i < DATA.length; i++) { for (let i = 0; i < DATA.length; i++) {
const d = DATA[i]; const d = DATA[i];
try { try {
const res = await digest(d.phrase); const proof = await generate_work(SALT, d.phrase, DIFFICULTY);
expect(res).toStrictEqual(d.hash); expect(proof.nonce).toBe(d.pow.nonce);
//expect(await w.digest(d.phrase)).toBe(d.hash); expect(proof.result).toBe(`${d.pow.result}`);
expect(score(d.hash)).toBe(d.difficulty); } catch (error) {
//let proof = await generate_work(SALT, d.phrase, DIFFICULTY); console.log(`${d.pow.nonce}${error}`);
//console.log( throw error;
// `saved nonce:${d.pow.nonce} proof result: ${proof.result}proof nonce: ${proof.nonce}` }
//); }
//expect(proof.nonce).toBe(d.pow.nonce); });
//expect(proof.result).toBe(d.pow.result);
test("Digest works", async () => {
for (let i = 0; i < DATA.length; i++) {
const d = DATA[i];
try {
const res = await digest(d.phrase);
expect(res).toStrictEqual(d.hash);
expect(score(d.hash)).toBe(d.difficulty);
} catch (error) { } catch (error) {
console.log(`${d.pow.nonce}${error}`); console.log(`${d.pow.nonce}${error}`);
throw error; throw error;