diff options
Diffstat (limited to 'packages/taler-util/src')
| -rw-r--r-- | packages/taler-util/src/backupTypes.ts | 5 | ||||
| -rw-r--r-- | packages/taler-util/src/helpers.ts | 11 | ||||
| -rw-r--r-- | packages/taler-util/src/talerCrypto.ts | 15 | ||||
| -rw-r--r-- | packages/taler-util/src/talerTypes.ts | 77 | ||||
| -rw-r--r-- | packages/taler-util/src/walletTypes.ts | 8 | 
5 files changed, 96 insertions, 20 deletions
diff --git a/packages/taler-util/src/backupTypes.ts b/packages/taler-util/src/backupTypes.ts index 70e52e63b..ecdd6fdf8 100644 --- a/packages/taler-util/src/backupTypes.ts +++ b/packages/taler-util/src/backupTypes.ts @@ -53,6 +53,7 @@  /**   * Imports.   */ +import { DenominationPubKey, UnblindedSignature } from "./talerTypes.js";  import { Duration, Timestamp } from "./time.js";  /** @@ -440,7 +441,7 @@ export interface BackupCoin {    /**     * Unblinded signature by the exchange.     */ -  denom_sig: string; +  denom_sig: UnblindedSignature;    /**     * Amount that's left on the coin. @@ -831,7 +832,7 @@ export interface BackupDenomination {    /**     * The denomination public key.     */ -  denom_pub: string; +  denom_pub: DenominationPubKey;    /**     * Fee for withdrawing. diff --git a/packages/taler-util/src/helpers.ts b/packages/taler-util/src/helpers.ts index 089602c9d..6c836c482 100644 --- a/packages/taler-util/src/helpers.ts +++ b/packages/taler-util/src/helpers.ts @@ -94,7 +94,7 @@ export function canonicalJson(obj: any): string {  /**   * Lexically compare two strings.   */ -export function strcmp(s1: string, s2: string): number { +export function strcmp(s1: string, s2: string): -1 | 0 | 1 {    if (s1 < s2) {      return -1;    } @@ -113,15 +113,14 @@ export function j2s(x: any): string {  /**   * Use this to filter null or undefined from an array in a type-safe fashion - *  + *   * example:   * const array: Array<T | undefined> = [undefined, null]   * const filtered: Array<T> = array.filter(notEmpty) - *  - * @param value  - * @returns  + * + * @param value + * @returns   */  export function notEmpty<T>(value: T | null | undefined): value is T {    return value !== null && value !== undefined;  } - diff --git a/packages/taler-util/src/talerCrypto.ts b/packages/taler-util/src/talerCrypto.ts index d8ac75dc0..b107786cd 100644 --- a/packages/taler-util/src/talerCrypto.ts +++ b/packages/taler-util/src/talerCrypto.ts @@ -24,6 +24,7 @@  import * as nacl from "./nacl-fast.js";  import { kdf } from "./kdf.js";  import bigint from "big-integer"; +import { DenominationPubKey } from "./talerTypes.js";  export function getRandomBytes(n: number): Uint8Array {    return nacl.randomBytes(n); @@ -348,6 +349,20 @@ export function hash(d: Uint8Array): Uint8Array {    return nacl.hash(d);  } +export function hashDenomPub(pub: DenominationPubKey): Uint8Array { +  if (pub.cipher !== 1) { +    throw Error("unsupported cipher"); +  } +  const pubBuf = decodeCrock(pub.rsa_public_key); +  const hashInputBuf = new ArrayBuffer(pubBuf.length + 4 + 4); +  const uint8ArrayBuf = new Uint8Array(hashInputBuf); +  const dv = new DataView(hashInputBuf); +  dv.setUint32(0, pub.age_mask ?? 0); +  dv.setUint32(4, pub.cipher); +  uint8ArrayBuf.set(pubBuf, 8); +  return nacl.hash(uint8ArrayBuf); +} +  export function eddsaSign(msg: Uint8Array, eddsaPriv: Uint8Array): Uint8Array {    const pair = nacl.crypto_sign_keyPair_fromSeed(eddsaPriv);    return nacl.sign_detached(msg, pair.secretKey); diff --git a/packages/taler-util/src/talerTypes.ts b/packages/taler-util/src/talerTypes.ts index 56110ec1e..04d700483 100644 --- a/packages/taler-util/src/talerTypes.ts +++ b/packages/taler-util/src/talerTypes.ts @@ -59,7 +59,7 @@ export class Denomination {    /**     * Public signing key of the denomination.     */ -  denom_pub: string; +  denom_pub: DenominationPubKey;    /**     * Fee for withdrawing. @@ -158,7 +158,7 @@ export interface RecoupRequest {    /**     * Signature over the coin public key by the denomination.     */ -  denom_sig: string; +  denom_sig: UnblindedSignature;    /**     * Coin public key of the coin we want to refund. @@ -198,6 +198,11 @@ export interface RecoupConfirmation {    old_coin_pub?: string;  } +export interface UnblindedSignature { +  cipher: DenomKeyType.Rsa; +  rsa_signature: string; +} +  /**   * Deposit permission for a single coin.   */ @@ -213,7 +218,7 @@ export interface CoinDepositPermission {    /**     * Signature made by the denomination public key.     */ -  ub_sig: string; +  ub_sig: UnblindedSignature;    /**     * The denomination public key associated with this coin.     */ @@ -779,8 +784,38 @@ export class TipPickupGetResponse {    expiration: Timestamp;  } +export enum DenomKeyType { +  Rsa = 1, +  ClauseSchnorr = 2, +} + +export interface RsaBlindedDenominationSignature { +  cipher: DenomKeyType.Rsa; +  blinded_rsa_signature: string; +} + +export interface CSBlindedDenominationSignature { +  cipher: DenomKeyType.ClauseSchnorr; +} + +export type BlindedDenominationSignature = +  | RsaBlindedDenominationSignature +  | CSBlindedDenominationSignature; + +export const codecForBlindedDenominationSignature = () => +  buildCodecForUnion<BlindedDenominationSignature>() +    .discriminateOn("cipher") +    .alternative(1, codecForRsaBlindedDenominationSignature()) +    .build("BlindedDenominationSignature"); + +export const codecForRsaBlindedDenominationSignature = () => +  buildCodecForObject<RsaBlindedDenominationSignature>() +    .property("cipher", codecForConstNumber(1)) +    .property("blinded_rsa_signature", codecForString()) +    .build("RsaBlindedDenominationSignature"); +  export class WithdrawResponse { -  ev_sig: string; +  ev_sig: BlindedDenominationSignature;  }  /** @@ -792,7 +827,7 @@ export interface CoinDumpJson {      /**       * The coin's denomination's public key.       */ -    denom_pub: string; +    denom_pub: DenominationPubKey;      /**       * Hash of denom_pub.       */ @@ -875,7 +910,7 @@ export interface ExchangeMeltResponse {  }  export interface ExchangeRevealItem { -  ev_sig: string; +  ev_sig: BlindedDenominationSignature;  }  export interface ExchangeRevealResponse { @@ -994,6 +1029,30 @@ export interface BankWithdrawalOperationPostResponse {    transfer_done: boolean;  } +export type DenominationPubKey = RsaDenominationPubKey | CsDenominationPubKey; + +export interface RsaDenominationPubKey { +  cipher: 1; +  rsa_public_key: string; +  age_mask?: number; +} + +export interface CsDenominationPubKey { +  cipher: 2; +} + +export const codecForDenominationPubKey = () => +  buildCodecForUnion<DenominationPubKey>() +    .discriminateOn("cipher") +    .alternative(1, codecForRsaDenominationPubKey()) +    .build("DenominationPubKey"); + +export const codecForRsaDenominationPubKey = () => +  buildCodecForObject<RsaDenominationPubKey>() +    .property("cipher", codecForConstNumber(1)) +    .property("rsa_public_key", codecForString()) +    .build("DenominationPubKey"); +  export const codecForBankWithdrawalOperationPostResponse = (): Codec<BankWithdrawalOperationPostResponse> =>    buildCodecForObject<BankWithdrawalOperationPostResponse>()      .property("transfer_done", codecForBoolean()) @@ -1008,7 +1067,7 @@ export type CoinPublicKeyString = string;  export const codecForDenomination = (): Codec<Denomination> =>    buildCodecForObject<Denomination>()      .property("value", codecForString()) -    .property("denom_pub", codecForString()) +    .property("denom_pub", codecForDenominationPubKey())      .property("fee_withdraw", codecForString())      .property("fee_deposit", codecForString())      .property("fee_refresh", codecForString()) @@ -1242,7 +1301,7 @@ export const codecForRecoupConfirmation = (): Codec<RecoupConfirmation> =>  export const codecForWithdrawResponse = (): Codec<WithdrawResponse> =>    buildCodecForObject<WithdrawResponse>() -    .property("ev_sig", codecForString()) +    .property("ev_sig", codecForBlindedDenominationSignature())      .build("WithdrawResponse");  export const codecForMerchantPayResponse = (): Codec<MerchantPayResponse> => @@ -1260,7 +1319,7 @@ export const codecForExchangeMeltResponse = (): Codec<ExchangeMeltResponse> =>  export const codecForExchangeRevealItem = (): Codec<ExchangeRevealItem> =>    buildCodecForObject<ExchangeRevealItem>() -    .property("ev_sig", codecForString()) +    .property("ev_sig", codecForBlindedDenominationSignature())      .build("ExchangeRevealItem");  export const codecForExchangeRevealResponse = (): Codec<ExchangeRevealResponse> => diff --git a/packages/taler-util/src/walletTypes.ts b/packages/taler-util/src/walletTypes.ts index 6e68ee080..879640e82 100644 --- a/packages/taler-util/src/walletTypes.ts +++ b/packages/taler-util/src/walletTypes.ts @@ -48,6 +48,8 @@ import {    AmountString,    codecForContractTerms,    ContractTerms, +  DenominationPubKey, +  UnblindedSignature,  } from "./talerTypes.js";  import { OrderShortInfo, codecForOrderShortInfo } from "./transactionsTypes.js";  import { BackupRecovery } from "./backupTypes.js"; @@ -454,7 +456,7 @@ export interface PlanchetCreationResult {    coinPriv: string;    reservePub: string;    denomPubHash: string; -  denomPub: string; +  denomPub: DenominationPubKey;    blindingKey: string;    withdrawSig: string;    coinEv: string; @@ -467,7 +469,7 @@ export interface PlanchetCreationRequest {    coinIndex: number;    value: AmountJson;    feeWithdraw: AmountJson; -  denomPub: string; +  denomPub: DenominationPubKey;    reservePub: string;    reservePriv: string;  } @@ -514,7 +516,7 @@ export interface DepositInfo {    feeDeposit: AmountJson;    wireInfoHash: string;    denomPubHash: string; -  denomSig: string; +  denomSig: UnblindedSignature;  }  export interface ExchangesListRespose {  | 
