gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 02/02: wallet-core: age restriction crypto WIP


From: gnunet
Subject: [taler-wallet-core] 02/02: wallet-core: age restriction crypto WIP
Date: Mon, 18 Apr 2022 21:23:54 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

commit 2e0b9b9cff43968a16eb9555cb6e128c979a604b
Author: Florian Dold <florian@dold.me>
AuthorDate: Mon Apr 18 21:23:37 2022 +0200

    wallet-core: age restriction crypto WIP
---
 packages/anastasis-core/src/crypto.ts  |  1 +
 packages/taler-util/src/nacl-fast.ts   | 84 ++++++++++++++++++++++++++++-
 packages/taler-util/src/payto.ts       | 10 ++--
 packages/taler-util/src/talerCrypto.ts | 98 ++++++++++++++++++++++++++++++++++
 4 files changed, 187 insertions(+), 6 deletions(-)

diff --git a/packages/anastasis-core/src/crypto.ts 
b/packages/anastasis-core/src/crypto.ts
index 9f412c6d..815f84c1 100644
--- a/packages/anastasis-core/src/crypto.ts
+++ b/packages/anastasis-core/src/crypto.ts
@@ -32,6 +32,7 @@ import { argon2id } from "hash-wasm";
 export type Flavor<T, FlavorT extends string> = T & {
   _flavor?: `anastasis.${FlavorT}`;
 };
+
 export type FlavorP<T, FlavorT extends string, S extends number> = T & {
   _flavor?: `anastasis.${FlavorT}`;
   _size?: S;
diff --git a/packages/taler-util/src/nacl-fast.ts 
b/packages/taler-util/src/nacl-fast.ts
index 809a1a48..82bdc7ce 100644
--- a/packages/taler-util/src/nacl-fast.ts
+++ b/packages/taler-util/src/nacl-fast.ts
@@ -2564,7 +2564,7 @@ function crypto_sign_keypair(
   return 0;
 }
 
-const L = new Float64Array([
+export const L = new Float64Array([
   0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde,
   0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10,
 ]);
@@ -3045,3 +3045,85 @@ export function crypto_core_ed25519_scalar_sub(
   modL(o, z);
   return o;
 }
+
+export function crypto_edx25519_private_key_create(): Uint8Array {
+  const seed = new Uint8Array(32);
+  randombytes(seed, 32);
+  return crypto_edx25519_private_key_create_from_seed(seed);
+}
+
+export function crypto_edx25519_private_key_create_from_seed(
+  seed: Uint8Array,
+): Uint8Array {
+  const pk = hash(seed);
+  pk[0] &= 248;
+  pk[31] &= 127;
+  pk[31] |= 64;
+  return pk;
+}
+
+export function crypto_edx25519_get_public(priv: Uint8Array): Uint8Array {
+  const pub = new Uint8Array(32);
+  if (0 != crypto_scalarmult_base_noclamp(pub.subarray(32), priv)) {
+    throw Error();
+  }
+  return pub;
+}
+
+export function crypto_edx25519_sign_detached(
+  m: Uint8Array,
+  skx: Uint8Array,
+  pkx: Uint8Array,
+): Uint8Array {
+  const n: number = m.length;
+  const d = new Uint8Array(64),
+    h = new Uint8Array(64),
+    r = new Uint8Array(64);
+  let i, j;
+  const x = new Float64Array(64);
+  const p = [gf(), gf(), gf(), gf()];
+
+  for (i = 0; i < 64; i++) d[i] = skx[i];
+
+  const sm = new Uint8Array(n + 64);
+
+  for (i = 0; i < n; i++) sm[64 + i] = m[i];
+  for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
+
+  crypto_hash(r, sm.subarray(32), n + 32);
+  reduce(r);
+  scalarbase(p, r);
+  pack(sm, p);
+
+  for (i = 32; i < 64; i++) sm[i] = pkx[i - 32];
+  crypto_hash(h, sm, n + 64);
+  reduce(h);
+
+  for (i = 0; i < 64; i++) x[i] = 0;
+  for (i = 0; i < 32; i++) x[i] = r[i];
+  for (i = 0; i < 32; i++) {
+    for (j = 0; j < 32; j++) {
+      x[i + j] += h[i] * d[j];
+    }
+  }
+
+  modL(sm.subarray(32), x);
+  return sm.subarray(64);
+}
+
+export function crypto_edx25519_sign_detached_verify(
+  msg: Uint8Array,
+  sig: Uint8Array,
+  publicKey: Uint8Array,
+): boolean {
+  checkArrayTypes(msg, sig, publicKey);
+  if (sig.length !== crypto_sign_BYTES) throw new Error("bad signature size");
+  if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
+    throw new Error("bad public key size");
+  const sm = new Uint8Array(crypto_sign_BYTES + msg.length);
+  const m = new Uint8Array(crypto_sign_BYTES + msg.length);
+  let i;
+  for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
+  for (i = 0; i < msg.length; i++) sm[i + crypto_sign_BYTES] = msg[i];
+  return crypto_sign_open(m, sm, sm.length, publicKey) >= 0;
+}
diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts
index 09d6856c..dd764e42 100644
--- a/packages/taler-util/src/payto.ts
+++ b/packages/taler-util/src/payto.ts
@@ -23,30 +23,30 @@ export type PaytoUri =
   | PaytoUriTalerBank
   | PaytoUriBitcoin;
 
-interface PaytoUriGeneric {
+export interface PaytoUriGeneric {
   targetType: string;
   targetPath: string;
   params: { [name: string]: string };
 }
 
-interface PaytoUriUnknown extends PaytoUriGeneric {
+export interface PaytoUriUnknown extends PaytoUriGeneric {
   isKnown: false;
 }
 
-interface PaytoUriIBAN extends PaytoUriGeneric {
+export interface PaytoUriIBAN extends PaytoUriGeneric {
   isKnown: true;
   targetType: "iban";
   iban: string;
 }
 
-interface PaytoUriTalerBank extends PaytoUriGeneric {
+export interface PaytoUriTalerBank extends PaytoUriGeneric {
   isKnown: true;
   targetType: "x-taler-bank";
   host: string;
   account: string;
 }
 
-interface PaytoUriBitcoin extends PaytoUriGeneric {
+export interface PaytoUriBitcoin extends PaytoUriGeneric {
   isKnown: true;
   targetType: "bitcoin";
   generateSegwitAddress: (r: string) => { addr1: string; addr2: string };
diff --git a/packages/taler-util/src/talerCrypto.ts 
b/packages/taler-util/src/talerCrypto.ts
index 6bcb592e..282d22d8 100644
--- a/packages/taler-util/src/talerCrypto.ts
+++ b/packages/taler-util/src/talerCrypto.ts
@@ -583,6 +583,11 @@ export interface EcdheKeyPair {
   ecdhePriv: Uint8Array;
 }
 
+export interface Edx25519Keypair {
+  edxPub: string;
+  edxPriv: string;
+}
+
 export function createEddsaKeyPair(): EddsaKeyPair {
   const eddsaPriv = nacl.randomBytes(32);
   const eddsaPub = eddsaGetPublic(eddsaPriv);
@@ -787,3 +792,96 @@ export class SignaturePurposeBuilder {
 export function buildSigPS(purposeNum: number): SignaturePurposeBuilder {
   return new SignaturePurposeBuilder(purposeNum);
 }
+
+export type Flavor<T, FlavorT extends string> = T & {
+  _flavor?: `taler.${FlavorT}`;
+};
+
+export type FlavorP<T, FlavorT extends string, S extends number> = T & {
+  _flavor?: `taler.${FlavorT}`;
+  _size?: S;
+};
+
+export type OpaqueData = Flavor<string, "OpaqueData">;
+export type Edx25519PublicKey = FlavorP<string, "Edx25519PublicKey", 32>;
+export type Edx25519PrivateKey = FlavorP<string, "Edx25519PrivateKey", 64>;
+export type Edx25519Signature = FlavorP<string, "Edx25519Signature", 64>;
+
+export namespace Edx25519 {
+  const revL = [
+    0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2,
+    0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10,
+  ];
+
+  const L = bigint.fromArray(revL.reverse(), 256, false);
+
+  export async function keyCreateFromSeed(
+    seed: OpaqueData,
+  ): Promise<Edx25519PrivateKey> {
+    return encodeCrock(
+      nacl.crypto_edx25519_private_key_create_from_seed(decodeCrock(seed)),
+    );
+  }
+
+  export async function keyCreate(): Promise<Edx25519PrivateKey> {
+    return encodeCrock(nacl.crypto_edx25519_private_key_create());
+  }
+
+  export async function getPublic(
+    priv: Edx25519PrivateKey,
+  ): Promise<Edx25519PublicKey> {
+    return encodeCrock(nacl.crypto_edx25519_get_public(decodeCrock(priv)));
+  }
+
+  export function sign(
+    msg: OpaqueData,
+    key: Edx25519PrivateKey,
+  ): Promise<Edx25519Signature> {
+    throw Error("not implemented");
+  }
+
+  async function deriveFactor(
+    pub: Edx25519PublicKey,
+    seed: OpaqueData,
+  ): Promise<OpaqueData> {
+    const res = kdfKw({
+      outputLength: 64,
+      salt: stringToBytes("edx2559-derivation"),
+      ikm: decodeCrock(pub),
+      info: decodeCrock(seed),
+    });
+
+    return encodeCrock(res);
+  }
+
+  export async function privateKeyDerive(
+    priv: Edx25519PrivateKey,
+    seed: OpaqueData,
+  ): Promise<Edx25519PrivateKey> {
+    const pub = await getPublic(priv);
+    const privDec = decodeCrock(priv);
+    const privA = privDec.subarray(0, 32).reverse();
+    const a = bigint.fromArray(Array.from(privA), 256, false);
+
+    const factorBuf = await deriveFactor(pub, seed);
+
+    const factor = bigint.fromArray(Array.from(factorBuf), 256, false);
+
+    const aPrime = a.divide(8).multiply(factor).multiply(8);
+
+    const bPrime = nacl.hash(
+      typedArrayConcat([privDec.subarray(32, 64), decodeCrock(factorBuf)]),
+    );
+
+    Uint8Array.from(aPrime.toArray(256).value)
+
+    throw Error("not implemented");
+  }
+
+  export function publicKeyDerive(
+    priv: Edx25519PrivateKey,
+    seed: OpaqueData,
+  ): Promise<Edx25519PublicKey> {
+    throw Error("not implemented")
+  }
+}

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]