document emscriptif.ts and fix mixin oddities
This commit is contained in:
parent
54e3bd2773
commit
87a8cd0a13
@ -18,9 +18,11 @@ import {AmountJson} from "./types";
|
|||||||
import Module, {EmscFunGen} from "src/emscripten/taler-emscripten-lib";
|
import Module, {EmscFunGen} from "src/emscripten/taler-emscripten-lib";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High-level interface to emscripten-compiled modules used
|
* Medium-level interface to emscripten-compiled modules used
|
||||||
* by the wallet.
|
* by the wallet.
|
||||||
*
|
*
|
||||||
|
* The high-level interface (using WebWorkers) is exposed in src/cryptoApi.ts.
|
||||||
|
*
|
||||||
* @author Florian Dold
|
* @author Florian Dold
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -35,6 +37,9 @@ const GNUNET_NO = 0;
|
|||||||
const GNUNET_SYSERR = -1;
|
const GNUNET_SYSERR = -1;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an emscripten-compiled function.
|
||||||
|
*/
|
||||||
const getEmsc: EmscFunGen = (name: string, ret: any, argTypes: any[]) => {
|
const getEmsc: EmscFunGen = (name: string, ret: any, argTypes: any[]) => {
|
||||||
return (...args: any[]) => {
|
return (...args: any[]) => {
|
||||||
return Module.ccall(name, ret, argTypes, args);
|
return Module.ccall(name, ret, argTypes, args);
|
||||||
@ -126,6 +131,10 @@ const emsc = {
|
|||||||
["number", "number", "number"]),
|
["number", "number", "number"]),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emscripten functions that allocate memory.
|
||||||
|
*/
|
||||||
const emscAlloc = {
|
const emscAlloc = {
|
||||||
get_amount: getEmsc("TALER_WRALL_get_amount",
|
get_amount: getEmsc("TALER_WRALL_get_amount",
|
||||||
"number",
|
"number",
|
||||||
@ -188,6 +197,9 @@ const emscAlloc = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constants for signatures purposes, define what the signatures vouches for.
|
||||||
|
*/
|
||||||
export enum SignaturePurpose {
|
export enum SignaturePurpose {
|
||||||
RESERVE_WITHDRAW = 1200,
|
RESERVE_WITHDRAW = 1200,
|
||||||
WALLET_COIN_DEPOSIT = 1201,
|
WALLET_COIN_DEPOSIT = 1201,
|
||||||
@ -196,17 +208,28 @@ export enum SignaturePurpose {
|
|||||||
TEST = 4242,
|
TEST = 4242,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Desired quality levels for random numbers.
|
||||||
|
*/
|
||||||
export enum RandomQuality {
|
export enum RandomQuality {
|
||||||
WEAK = 0,
|
WEAK = 0,
|
||||||
STRONG = 1,
|
STRONG = 1,
|
||||||
NONCE = 2
|
NONCE = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object that is allocated in some arena.
|
||||||
|
*/
|
||||||
interface ArenaObject {
|
interface ArenaObject {
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context for cummulative hashing.
|
||||||
|
*/
|
||||||
export class HashContext implements ArenaObject {
|
export class HashContext implements ArenaObject {
|
||||||
private hashContextPtr: number | undefined;
|
private hashContextPtr: number | undefined;
|
||||||
|
|
||||||
@ -214,6 +237,9 @@ export class HashContext implements ArenaObject {
|
|||||||
this.hashContextPtr = emscAlloc.hash_context_start();
|
this.hashContextPtr = emscAlloc.hash_context_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add data to be hashed.
|
||||||
|
*/
|
||||||
read(obj: PackedArenaObject): void {
|
read(obj: PackedArenaObject): void {
|
||||||
if (!this.hashContextPtr) {
|
if (!this.hashContextPtr) {
|
||||||
throw Error("assertion failed");
|
throw Error("assertion failed");
|
||||||
@ -221,6 +247,9 @@ export class HashContext implements ArenaObject {
|
|||||||
emsc.hash_context_read(this.hashContextPtr, obj.nativePtr, obj.size());
|
emsc.hash_context_read(this.hashContextPtr, obj.nativePtr, obj.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish the hash computation.
|
||||||
|
*/
|
||||||
finish(h: HashCode) {
|
finish(h: HashCode) {
|
||||||
if (!this.hashContextPtr) {
|
if (!this.hashContextPtr) {
|
||||||
throw Error("assertion failed");
|
throw Error("assertion failed");
|
||||||
@ -229,6 +258,9 @@ export class HashContext implements ArenaObject {
|
|||||||
emsc.hash_context_finish(this.hashContextPtr, h.nativePtr);
|
emsc.hash_context_finish(this.hashContextPtr, h.nativePtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abort hashing without computing the result.
|
||||||
|
*/
|
||||||
destroy(): void {
|
destroy(): void {
|
||||||
if (this.hashContextPtr) {
|
if (this.hashContextPtr) {
|
||||||
emsc.hash_context_abort(this.hashContextPtr);
|
emsc.hash_context_abort(this.hashContextPtr);
|
||||||
@ -238,6 +270,9 @@ export class HashContext implements ArenaObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arena object that points to an allocaed block of memory.
|
||||||
|
*/
|
||||||
abstract class MallocArenaObject implements ArenaObject {
|
abstract class MallocArenaObject implements ArenaObject {
|
||||||
protected _nativePtr: number | undefined = undefined;
|
protected _nativePtr: number | undefined = undefined;
|
||||||
|
|
||||||
@ -245,7 +280,6 @@ abstract class MallocArenaObject implements ArenaObject {
|
|||||||
* Is this a weak reference to the underlying memory?
|
* Is this a weak reference to the underlying memory?
|
||||||
*/
|
*/
|
||||||
isWeak = false;
|
isWeak = false;
|
||||||
arena: Arena;
|
|
||||||
|
|
||||||
destroy(): void {
|
destroy(): void {
|
||||||
if (this._nativePtr && !this.isWeak) {
|
if (this._nativePtr && !this.isWeak) {
|
||||||
@ -262,7 +296,6 @@ abstract class MallocArenaObject implements ArenaObject {
|
|||||||
arena = arenaStack[arenaStack.length - 1];
|
arena = arenaStack[arenaStack.length - 1];
|
||||||
}
|
}
|
||||||
arena.put(this);
|
arena.put(this);
|
||||||
this.arena = arena;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc(size: number) {
|
alloc(size: number) {
|
||||||
@ -291,6 +324,10 @@ abstract class MallocArenaObject implements ArenaObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An arena stores objects that will be deallocated
|
||||||
|
* at the same time.
|
||||||
|
*/
|
||||||
interface Arena {
|
interface Arena {
|
||||||
put(obj: ArenaObject): void;
|
put(obj: ArenaObject): void;
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
@ -352,6 +389,9 @@ let arenaStack: Arena[] = [];
|
|||||||
arenaStack.push(new SyncArena());
|
arenaStack.push(new SyncArena());
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of monetary value in a given currency.
|
||||||
|
*/
|
||||||
export class Amount extends MallocArenaObject {
|
export class Amount extends MallocArenaObject {
|
||||||
constructor(args?: AmountJson, arena?: Arena) {
|
constructor(args?: AmountJson, arena?: Arena) {
|
||||||
super(arena);
|
super(arena);
|
||||||
@ -547,6 +587,9 @@ abstract class PackedArenaObject extends MallocArenaObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount, encoded for network transmission.
|
||||||
|
*/
|
||||||
export class AmountNbo extends PackedArenaObject {
|
export class AmountNbo extends PackedArenaObject {
|
||||||
size() {
|
size() {
|
||||||
return 24;
|
return 24;
|
||||||
@ -563,6 +606,46 @@ export class AmountNbo extends PackedArenaObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a packed arena object from the base32 crockford encoding.
|
||||||
|
*/
|
||||||
|
function fromCrock<T extends PackedArenaObject>(s: string, ctor: Ctor<T>): T {
|
||||||
|
let x: T = new ctor();
|
||||||
|
x.alloc();
|
||||||
|
x.loadCrock(s);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a packed arena object from the base32 crockford encoding for objects
|
||||||
|
* that have a special decoding function.
|
||||||
|
*/
|
||||||
|
function fromCrockDecoded<T extends MallocArenaObject>(s: string, ctor: Ctor<T>, decodeFn: (p: number, s: number) => number): T {
|
||||||
|
let obj = new ctor();
|
||||||
|
let buf = ByteArray.fromCrock(s);
|
||||||
|
obj.nativePtr = decodeFn(buf.nativePtr, buf.size());
|
||||||
|
buf.destroy();
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode an object using a special encoding function.
|
||||||
|
*/
|
||||||
|
function encode<T extends MallocArenaObject>(obj: T, encodeFn: any, arena?: Arena): ByteArray {
|
||||||
|
let ptr = emscAlloc.malloc(PTR_SIZE);
|
||||||
|
let len = encodeFn(obj.nativePtr, ptr);
|
||||||
|
let res = new ByteArray(len, undefined, arena);
|
||||||
|
res.nativePtr = Module.getValue(ptr, '*');
|
||||||
|
emsc.free(ptr);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private EdDSA key.
|
||||||
|
*/
|
||||||
export class EddsaPrivateKey extends PackedArenaObject {
|
export class EddsaPrivateKey extends PackedArenaObject {
|
||||||
static create(a?: Arena): EddsaPrivateKey {
|
static create(a?: Arena): EddsaPrivateKey {
|
||||||
let obj = new EddsaPrivateKey(a);
|
let obj = new EddsaPrivateKey(a);
|
||||||
@ -580,9 +663,10 @@ export class EddsaPrivateKey extends PackedArenaObject {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCrock: (s: string) => EddsaPrivateKey;
|
static fromCrock(s: string): EddsaPrivateKey {
|
||||||
|
return fromCrock(s, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mixinStatic(EddsaPrivateKey, fromCrock);
|
|
||||||
|
|
||||||
|
|
||||||
export class EcdsaPrivateKey extends PackedArenaObject {
|
export class EcdsaPrivateKey extends PackedArenaObject {
|
||||||
@ -602,9 +686,10 @@ export class EcdsaPrivateKey extends PackedArenaObject {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCrock: (s: string) => EcdsaPrivateKey;
|
static fromCrock(s: string): EcdsaPrivateKey {
|
||||||
|
return fromCrock(s, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mixinStatic(EcdsaPrivateKey, fromCrock);
|
|
||||||
|
|
||||||
|
|
||||||
export class EcdhePrivateKey extends PackedArenaObject {
|
export class EcdhePrivateKey extends PackedArenaObject {
|
||||||
@ -624,38 +709,17 @@ export class EcdhePrivateKey extends PackedArenaObject {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCrock: (s: string) => EcdhePrivateKey;
|
static fromCrock(s: string): EcdhePrivateKey {
|
||||||
}
|
return fromCrock(s, this);
|
||||||
mixinStatic(EcdhePrivateKey, fromCrock);
|
}
|
||||||
|
|
||||||
|
|
||||||
function fromCrock(s: string) {
|
|
||||||
let x = new this();
|
|
||||||
x.alloc();
|
|
||||||
x.loadCrock(s);
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function mixin(obj: any, method: any, name?: string) {
|
/**
|
||||||
if (!name) {
|
* Constructor for a given type.
|
||||||
name = method.name;
|
*/
|
||||||
}
|
interface Ctor<T> {
|
||||||
if (!name) {
|
new(): T
|
||||||
throw Error("Mixin needs a name.");
|
|
||||||
}
|
|
||||||
obj.prototype[method.name] = method;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function mixinStatic(obj: any, method: any, name?: string) {
|
|
||||||
if (!name) {
|
|
||||||
name = method.name;
|
|
||||||
}
|
|
||||||
if (!name) {
|
|
||||||
throw Error("Mixin needs a name.");
|
|
||||||
}
|
|
||||||
obj[method.name] = method;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -664,18 +728,20 @@ export class EddsaPublicKey extends PackedArenaObject {
|
|||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCrock: (s: string) => EddsaPublicKey;
|
static fromCrock(s: string): EddsaPublicKey {
|
||||||
|
return fromCrock(s, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mixinStatic(EddsaPublicKey, fromCrock);
|
|
||||||
|
|
||||||
export class EcdsaPublicKey extends PackedArenaObject {
|
export class EcdsaPublicKey extends PackedArenaObject {
|
||||||
size() {
|
size() {
|
||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCrock: (s: string) => EcdsaPublicKey;
|
static fromCrock(s: string): EcdsaPublicKey {
|
||||||
|
return fromCrock(s, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mixinStatic(EcdsaPublicKey, fromCrock);
|
|
||||||
|
|
||||||
|
|
||||||
export class EcdhePublicKey extends PackedArenaObject {
|
export class EcdhePublicKey extends PackedArenaObject {
|
||||||
@ -683,36 +749,9 @@ export class EcdhePublicKey extends PackedArenaObject {
|
|||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCrock: (s: string) => EcdhePublicKey;
|
static fromCrock(s: string): EcdhePublicKey {
|
||||||
}
|
return fromCrock(s, this);
|
||||||
mixinStatic(EcdhePublicKey, fromCrock);
|
|
||||||
|
|
||||||
|
|
||||||
function makeFromCrock(decodeFn: (p: number, s: number) => number) {
|
|
||||||
function fromCrock(s: string, a?: Arena) {
|
|
||||||
let obj = new this(a);
|
|
||||||
let buf = ByteArray.fromCrock(s);
|
|
||||||
obj.nativePtr = decodeFn(buf.nativePtr, buf.size());
|
|
||||||
buf.destroy();
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fromCrock;
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeToCrock(encodeFn: (po: number,
|
|
||||||
ps: number) => number): () => string {
|
|
||||||
function toCrock() {
|
|
||||||
let ptr = emscAlloc.malloc(PTR_SIZE);
|
|
||||||
let size = emscAlloc.rsa_blinding_key_encode(this.nativePtr, ptr);
|
|
||||||
let res = new ByteArray(size, Module.getValue(ptr, '*'));
|
|
||||||
let s = res.toCrock();
|
|
||||||
emsc.free(ptr);
|
|
||||||
res.destroy();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
return toCrock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RsaBlindingKeySecret extends PackedArenaObject {
|
export class RsaBlindingKeySecret extends PackedArenaObject {
|
||||||
@ -730,9 +769,10 @@ export class RsaBlindingKeySecret extends PackedArenaObject {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCrock: (s: string) => RsaBlindingKeySecret;
|
static fromCrock(s: string): RsaBlindingKeySecret {
|
||||||
|
return fromCrock(s, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mixinStatic(RsaBlindingKeySecret, fromCrock);
|
|
||||||
|
|
||||||
|
|
||||||
export class HashCode extends PackedArenaObject {
|
export class HashCode extends PackedArenaObject {
|
||||||
@ -740,14 +780,15 @@ export class HashCode extends PackedArenaObject {
|
|||||||
return 64;
|
return 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCrock: (s: string) => HashCode;
|
static fromCrock(s: string): HashCode {
|
||||||
|
return fromCrock(s, this);
|
||||||
|
}
|
||||||
|
|
||||||
random(qual: RandomQuality = RandomQuality.STRONG) {
|
random(qual: RandomQuality = RandomQuality.STRONG) {
|
||||||
this.alloc();
|
this.alloc();
|
||||||
emsc.hash_create_random(qual, this.nativePtr);
|
emsc.hash_create_random(qual, this.nativePtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mixinStatic(HashCode, fromCrock);
|
|
||||||
|
|
||||||
|
|
||||||
export class ByteArray extends PackedArenaObject {
|
export class ByteArray extends PackedArenaObject {
|
||||||
@ -784,6 +825,8 @@ export class ByteArray extends PackedArenaObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static fromCrock(s: string, a?: Arena): ByteArray {
|
static fromCrock(s: string, a?: Arena): ByteArray {
|
||||||
|
// this one is a bit more complicated than the other fromCrock functions,
|
||||||
|
// since we don't have a fixed size
|
||||||
let byteLength = countUtf8Bytes(s);
|
let byteLength = countUtf8Bytes(s);
|
||||||
let hstr = emscAlloc.malloc(byteLength + 1);
|
let hstr = emscAlloc.malloc(byteLength + 1);
|
||||||
Module.stringToUTF8(s, hstr, byteLength + 1);
|
Module.stringToUTF8(s, hstr, byteLength + 1);
|
||||||
@ -799,6 +842,10 @@ export class ByteArray extends PackedArenaObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data to sign, together with a header that includes a purpose id
|
||||||
|
* and size.
|
||||||
|
*/
|
||||||
export class EccSignaturePurpose extends PackedArenaObject {
|
export class EccSignaturePurpose extends PackedArenaObject {
|
||||||
size() {
|
size() {
|
||||||
return this.payloadSize + 8;
|
return this.payloadSize + 8;
|
||||||
@ -1090,27 +1137,11 @@ export class DenominationKeyValidityPS extends SignatureStruct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface Encodeable {
|
export class RsaPublicKey extends MallocArenaObject {
|
||||||
encode(arena?: Arena): ByteArray;
|
static fromCrock(s: string): RsaPublicKey {
|
||||||
}
|
return fromCrockDecoded(s, this, emscAlloc.rsa_public_key_decode);
|
||||||
|
|
||||||
function makeEncode(encodeFn: any) {
|
|
||||||
function encode(arena?: Arena) {
|
|
||||||
let ptr = emscAlloc.malloc(PTR_SIZE);
|
|
||||||
let len = encodeFn(this.nativePtr, ptr);
|
|
||||||
let res = new ByteArray(len, undefined, arena);
|
|
||||||
res.nativePtr = Module.getValue(ptr, '*');
|
|
||||||
emsc.free(ptr);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return encode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class RsaPublicKey extends MallocArenaObject implements Encodeable {
|
|
||||||
static fromCrock: (s: string, a?: Arena) => RsaPublicKey;
|
|
||||||
|
|
||||||
toCrock() {
|
toCrock() {
|
||||||
return this.encode().toCrock();
|
return this.encode().toCrock();
|
||||||
}
|
}
|
||||||
@ -1120,10 +1151,10 @@ export class RsaPublicKey extends MallocArenaObject implements Encodeable {
|
|||||||
this.nativePtr = 0;
|
this.nativePtr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
encode: (arena?: Arena) => ByteArray;
|
encode(arena?: Arena): ByteArray {
|
||||||
|
return encode(this, emscAlloc.rsa_public_key_encode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mixinStatic(RsaPublicKey, makeFromCrock(emscAlloc.rsa_public_key_decode));
|
|
||||||
mixin(RsaPublicKey, makeEncode(emscAlloc.rsa_public_key_encode));
|
|
||||||
|
|
||||||
|
|
||||||
export class EddsaSignature extends PackedArenaObject {
|
export class EddsaSignature extends PackedArenaObject {
|
||||||
@ -1133,20 +1164,25 @@ export class EddsaSignature extends PackedArenaObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class RsaSignature extends MallocArenaObject implements Encodeable {
|
export class RsaSignature extends MallocArenaObject {
|
||||||
static fromCrock: (s: string, a?: Arena) => RsaSignature;
|
static fromCrock(s: string, a?: Arena) {
|
||||||
|
return fromCrockDecoded(s, this, emscAlloc.rsa_signature_decode);
|
||||||
|
}
|
||||||
|
|
||||||
encode: (arena?: Arena) => ByteArray;
|
encode(arena?: Arena): ByteArray {
|
||||||
|
return encode(this, emscAlloc.rsa_signature_encode);
|
||||||
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
emsc.rsa_signature_free(this.nativePtr);
|
emsc.rsa_signature_free(this.nativePtr);
|
||||||
this.nativePtr = 0;
|
this.nativePtr = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mixinStatic(RsaSignature, makeFromCrock(emscAlloc.rsa_signature_decode));
|
|
||||||
mixin(RsaSignature, makeEncode(emscAlloc.rsa_signature_encode));
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blind a value so it can be blindly signed.
|
||||||
|
*/
|
||||||
export function rsaBlind(hashCode: HashCode,
|
export function rsaBlind(hashCode: HashCode,
|
||||||
blindingKey: RsaBlindingKeySecret,
|
blindingKey: RsaBlindingKeySecret,
|
||||||
pkey: RsaPublicKey,
|
pkey: RsaPublicKey,
|
||||||
@ -1170,6 +1206,9 @@ export function rsaBlind(hashCode: HashCode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign data using EdDSA.
|
||||||
|
*/
|
||||||
export function eddsaSign(purpose: EccSignaturePurpose,
|
export function eddsaSign(purpose: EccSignaturePurpose,
|
||||||
priv: EddsaPrivateKey,
|
priv: EddsaPrivateKey,
|
||||||
a?: Arena): EddsaSignature {
|
a?: Arena): EddsaSignature {
|
||||||
@ -1183,6 +1222,9 @@ export function eddsaSign(purpose: EccSignaturePurpose,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify EdDSA-signed data.
|
||||||
|
*/
|
||||||
export function eddsaVerify(purposeNum: number,
|
export function eddsaVerify(purposeNum: number,
|
||||||
verify: EccSignaturePurpose,
|
verify: EccSignaturePurpose,
|
||||||
sig: EddsaSignature,
|
sig: EddsaSignature,
|
||||||
@ -1196,6 +1238,9 @@ export function eddsaVerify(purposeNum: number,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unblind a blindly signed value.
|
||||||
|
*/
|
||||||
export function rsaUnblind(sig: RsaSignature,
|
export function rsaUnblind(sig: RsaSignature,
|
||||||
bk: RsaBlindingKeySecret,
|
bk: RsaBlindingKeySecret,
|
||||||
pk: RsaPublicKey,
|
pk: RsaPublicKey,
|
||||||
@ -1210,12 +1255,15 @@ export function rsaUnblind(sig: RsaSignature,
|
|||||||
|
|
||||||
type TransferSecretP = HashCode;
|
type TransferSecretP = HashCode;
|
||||||
|
|
||||||
|
|
||||||
export interface FreshCoin {
|
export interface FreshCoin {
|
||||||
priv: EddsaPrivateKey;
|
priv: EddsaPrivateKey;
|
||||||
blindingKey: RsaBlindingKeySecret;
|
blindingKey: RsaBlindingKeySecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Diffie-Hellman operation between an ECDHE private key
|
||||||
|
* and an EdDSA public key.
|
||||||
|
*/
|
||||||
export function ecdhEddsa(priv: EcdhePrivateKey,
|
export function ecdhEddsa(priv: EcdhePrivateKey,
|
||||||
pub: EddsaPublicKey): HashCode {
|
pub: EddsaPublicKey): HashCode {
|
||||||
let h = new HashCode();
|
let h = new HashCode();
|
||||||
@ -1227,6 +1275,10 @@ export function ecdhEddsa(priv: EcdhePrivateKey,
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive a fresh coin from the given seed. Used during refreshing.
|
||||||
|
*/
|
||||||
export function setupFreshCoin(secretSeed: TransferSecretP,
|
export function setupFreshCoin(secretSeed: TransferSecretP,
|
||||||
coinIndex: number): FreshCoin {
|
coinIndex: number): FreshCoin {
|
||||||
let priv = new EddsaPrivateKey();
|
let priv = new EddsaPrivateKey();
|
||||||
|
Loading…
Reference in New Issue
Block a user