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 & {
|
export type Flavor<T, FlavorT extends string> = T & {
|
||||||
_flavor?: `anastasis.${FlavorT}`;
|
_flavor?: `anastasis.${FlavorT}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FlavorP<T, FlavorT extends string, S extends number> = T & {
|
export type FlavorP<T, FlavorT extends string, S extends number> = T & {
|
||||||
_flavor?: `anastasis.${FlavorT}`;
|
_flavor?: `anastasis.${FlavorT}`;
|
||||||
_size?: S;
|
_size?: S;
|
||||||
|
@ -2564,7 +2564,7 @@ function crypto_sign_keypair(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const L = new Float64Array([
|
export const L = new Float64Array([
|
||||||
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde,
|
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,
|
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);
|
modL(o, z);
|
||||||
return o;
|
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
|
| PaytoUriTalerBank
|
||||||
| PaytoUriBitcoin;
|
| PaytoUriBitcoin;
|
||||||
|
|
||||||
interface PaytoUriGeneric {
|
export interface PaytoUriGeneric {
|
||||||
targetType: string;
|
targetType: string;
|
||||||
targetPath: string;
|
targetPath: string;
|
||||||
params: { [name: string]: string };
|
params: { [name: string]: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PaytoUriUnknown extends PaytoUriGeneric {
|
export interface PaytoUriUnknown extends PaytoUriGeneric {
|
||||||
isKnown: false;
|
isKnown: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PaytoUriIBAN extends PaytoUriGeneric {
|
export interface PaytoUriIBAN extends PaytoUriGeneric {
|
||||||
isKnown: true;
|
isKnown: true;
|
||||||
targetType: "iban";
|
targetType: "iban";
|
||||||
iban: string;
|
iban: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PaytoUriTalerBank extends PaytoUriGeneric {
|
export interface PaytoUriTalerBank extends PaytoUriGeneric {
|
||||||
isKnown: true;
|
isKnown: true;
|
||||||
targetType: "x-taler-bank";
|
targetType: "x-taler-bank";
|
||||||
host: string;
|
host: string;
|
||||||
account: string;
|
account: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PaytoUriBitcoin extends PaytoUriGeneric {
|
export interface PaytoUriBitcoin extends PaytoUriGeneric {
|
||||||
isKnown: true;
|
isKnown: true;
|
||||||
targetType: "bitcoin";
|
targetType: "bitcoin";
|
||||||
generateSegwitAddress: (r: string) => { addr1: string; addr2: string };
|
generateSegwitAddress: (r: string) => { addr1: string; addr2: string };
|
||||||
|
@ -583,6 +583,11 @@ export interface EcdheKeyPair {
|
|||||||
ecdhePriv: Uint8Array;
|
ecdhePriv: Uint8Array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Edx25519Keypair {
|
||||||
|
edxPub: string;
|
||||||
|
edxPriv: string;
|
||||||
|
}
|
||||||
|
|
||||||
export function createEddsaKeyPair(): EddsaKeyPair {
|
export function createEddsaKeyPair(): EddsaKeyPair {
|
||||||
const eddsaPriv = nacl.randomBytes(32);
|
const eddsaPriv = nacl.randomBytes(32);
|
||||||
const eddsaPub = eddsaGetPublic(eddsaPriv);
|
const eddsaPub = eddsaGetPublic(eddsaPriv);
|
||||||
@ -787,3 +792,96 @@ export class SignaturePurposeBuilder {
|
|||||||
export function buildSigPS(purposeNum: number): SignaturePurposeBuilder {
|
export function buildSigPS(purposeNum: number): SignaturePurposeBuilder {
|
||||||
return new SignaturePurposeBuilder(purposeNum);
|
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