wallet-core: age restriction crypto WIP
This commit is contained in:
parent
68b4d0c4de
commit
2e0b9b9cff
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 };
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user