clause schnorr

This commit is contained in:
Florian Dold 2022-02-02 23:44:36 +01:00
parent 003ba5e91b
commit f5ff4afae6
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
7 changed files with 84 additions and 26 deletions

View File

@ -616,8 +616,21 @@ export function hashDenomPub(pub: DenominationPubKey): Uint8Array {
return nacl.hash(uint8ArrayBuf); return nacl.hash(uint8ArrayBuf);
} else if (pub.cipher === DenomKeyType.LegacyRsa) { } else if (pub.cipher === DenomKeyType.LegacyRsa) {
return hash(decodeCrock(pub.rsa_public_key)); return hash(decodeCrock(pub.rsa_public_key));
} else if (pub.cipher === DenomKeyType.ClauseSchnorr) {
const pubBuf = decodeCrock(pub.cs_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);
} else { } else {
throw Error(`unsupported cipher (${pub.cipher}), unable to hash`); throw Error(
`unsupported cipher (${
(pub as DenominationPubKey).cipher
}), unable to hash`,
);
} }
} }

View File

@ -1123,7 +1123,8 @@ export interface RsaDenominationPubKey {
export interface CsDenominationPubKey { export interface CsDenominationPubKey {
cipher: DenomKeyType.ClauseSchnorr; cipher: DenomKeyType.ClauseSchnorr;
// FIXME: finish definition age_mask: number;
cs_public_key: string;
} }
export namespace DenominationPubKey { export namespace DenominationPubKey {
@ -1151,6 +1152,16 @@ export namespace DenominationPubKey {
return 1; return 1;
} }
return strcmp(p1.rsa_public_key, p2.rsa_public_key); return strcmp(p1.rsa_public_key, p2.rsa_public_key);
} else if (
p1.cipher === DenomKeyType.ClauseSchnorr &&
p2.cipher === DenomKeyType.ClauseSchnorr
) {
if ((p1.age_mask ?? 0) < (p2.age_mask ?? 0)) {
return -1;
} else if ((p1.age_mask ?? 0) > (p2.age_mask ?? 0)) {
return 1;
}
return strcmp(p1.cs_public_key, p2.cs_public_key);
} else { } else {
throw Error("unsupported cipher"); throw Error("unsupported cipher");
} }
@ -1171,6 +1182,7 @@ export const codecForDenominationPubKey = () =>
buildCodecForUnion<DenominationPubKey>() buildCodecForUnion<DenominationPubKey>()
.discriminateOn("cipher") .discriminateOn("cipher")
.alternative(1, codecForRsaDenominationPubKey()) .alternative(1, codecForRsaDenominationPubKey())
.alternative(2, codecForCsDenominationPubKey())
.alternative(3, codecForLegacyRsaDenominationPubKey()) .alternative(3, codecForLegacyRsaDenominationPubKey())
.build("DenominationPubKey"); .build("DenominationPubKey");
@ -1186,6 +1198,12 @@ export const codecForLegacyRsaDenominationPubKey = () =>
.property("rsa_public_key", codecForString()) .property("rsa_public_key", codecForString())
.build("LegacyRsaDenominationPubKey"); .build("LegacyRsaDenominationPubKey");
export const codecForCsDenominationPubKey = () =>
buildCodecForObject<CsDenominationPubKey>()
.property("cipher", codecForConstNumber(2))
.property("cs_public_key", codecForString())
.build("CsDenominationPubKey");
export const codecForBankWithdrawalOperationPostResponse = export const codecForBankWithdrawalOperationPostResponse =
(): Codec<BankWithdrawalOperationPostResponse> => (): Codec<BankWithdrawalOperationPostResponse> =>
buildCodecForObject<BankWithdrawalOperationPostResponse>() buildCodecForObject<BankWithdrawalOperationPostResponse>()

View File

@ -14,7 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
export interface CoinConfig { export interface CoinCoinfigCommon {
name: string; name: string;
value: string; value: string;
durationWithdraw: string; durationWithdraw: string;
@ -24,10 +24,24 @@ export interface CoinConfig {
feeDeposit: string; feeDeposit: string;
feeRefresh: string; feeRefresh: string;
feeRefund: string; feeRefund: string;
}
export interface CoinConfigRsa extends CoinCoinfigCommon {
cipher: "RSA";
rsaKeySize: number; rsaKeySize: number;
} }
const coinCommon = { /**
* Clause Schnorr coin config.
*/
export interface CoinConfigCs extends CoinCoinfigCommon {
cipher: "CS";
}
export type CoinConfig = CoinConfigRsa | CoinConfigCs;
const coinRsaCommon = {
cipher: "RSA" as const,
durationLegal: "3 years", durationLegal: "3 years",
durationSpend: "2 years", durationSpend: "2 years",
durationWithdraw: "7 days", durationWithdraw: "7 days",
@ -35,7 +49,7 @@ const coinCommon = {
}; };
export const coin_ct1 = (curr: string): CoinConfig => ({ export const coin_ct1 = (curr: string): CoinConfig => ({
...coinCommon, ...coinRsaCommon,
name: `${curr}_ct1`, name: `${curr}_ct1`,
value: `${curr}:0.01`, value: `${curr}:0.01`,
feeDeposit: `${curr}:0.00`, feeDeposit: `${curr}:0.00`,
@ -45,7 +59,7 @@ export const coin_ct1 = (curr: string): CoinConfig => ({
}); });
export const coin_ct10 = (curr: string): CoinConfig => ({ export const coin_ct10 = (curr: string): CoinConfig => ({
...coinCommon, ...coinRsaCommon,
name: `${curr}_ct10`, name: `${curr}_ct10`,
value: `${curr}:0.10`, value: `${curr}:0.10`,
feeDeposit: `${curr}:0.01`, feeDeposit: `${curr}:0.01`,
@ -55,7 +69,7 @@ export const coin_ct10 = (curr: string): CoinConfig => ({
}); });
export const coin_u1 = (curr: string): CoinConfig => ({ export const coin_u1 = (curr: string): CoinConfig => ({
...coinCommon, ...coinRsaCommon,
name: `${curr}_u1`, name: `${curr}_u1`,
value: `${curr}:1`, value: `${curr}:1`,
feeDeposit: `${curr}:0.02`, feeDeposit: `${curr}:0.02`,
@ -65,7 +79,7 @@ export const coin_u1 = (curr: string): CoinConfig => ({
}); });
export const coin_u2 = (curr: string): CoinConfig => ({ export const coin_u2 = (curr: string): CoinConfig => ({
...coinCommon, ...coinRsaCommon,
name: `${curr}_u2`, name: `${curr}_u2`,
value: `${curr}:2`, value: `${curr}:2`,
feeDeposit: `${curr}:0.02`, feeDeposit: `${curr}:0.02`,
@ -75,7 +89,7 @@ export const coin_u2 = (curr: string): CoinConfig => ({
}); });
export const coin_u4 = (curr: string): CoinConfig => ({ export const coin_u4 = (curr: string): CoinConfig => ({
...coinCommon, ...coinRsaCommon,
name: `${curr}_u4`, name: `${curr}_u4`,
value: `${curr}:4`, value: `${curr}:4`,
feeDeposit: `${curr}:0.02`, feeDeposit: `${curr}:0.02`,
@ -85,7 +99,7 @@ export const coin_u4 = (curr: string): CoinConfig => ({
}); });
export const coin_u8 = (curr: string): CoinConfig => ({ export const coin_u8 = (curr: string): CoinConfig => ({
...coinCommon, ...coinRsaCommon,
name: `${curr}_u8`, name: `${curr}_u8`,
value: `${curr}:8`, value: `${curr}:8`,
feeDeposit: `${curr}:0.16`, feeDeposit: `${curr}:0.16`,
@ -95,7 +109,7 @@ export const coin_u8 = (curr: string): CoinConfig => ({
}); });
const coin_u10 = (curr: string): CoinConfig => ({ const coin_u10 = (curr: string): CoinConfig => ({
...coinCommon, ...coinRsaCommon,
name: `${curr}_u10`, name: `${curr}_u10`,
value: `${curr}:10`, value: `${curr}:10`,
feeDeposit: `${curr}:0.2`, feeDeposit: `${curr}:0.2`,
@ -114,16 +128,6 @@ export const defaultCoinConfig = [
coin_u10, coin_u10,
]; ];
const coinCheapCommon = (curr: string) => ({
durationLegal: "3 years",
durationSpend: "2 years",
durationWithdraw: "7 days",
rsaKeySize: 1024,
feeRefresh: `${curr}:0.2`,
feeRefund: `${curr}:0.2`,
feeWithdraw: `${curr}:0.2`,
});
export function makeNoFeeCoinConfig(curr: string): CoinConfig[] { export function makeNoFeeCoinConfig(curr: string): CoinConfig[] {
const cc: CoinConfig[] = []; const cc: CoinConfig[] = [];
@ -134,6 +138,7 @@ export function makeNoFeeCoinConfig(curr: string): CoinConfig[] {
const cent = ct % 100; const cent = ct % 100;
cc.push({ cc.push({
cipher: "RSA",
durationLegal: "3 years", durationLegal: "3 years",
durationSpend: "2 years", durationSpend: "2 years",
durationWithdraw: "7 days", durationWithdraw: "7 days",

View File

@ -430,7 +430,14 @@ function setCoin(config: Configuration, c: CoinConfig) {
config.setString(s, "fee_withdraw", c.feeWithdraw); config.setString(s, "fee_withdraw", c.feeWithdraw);
config.setString(s, "fee_refresh", c.feeRefresh); config.setString(s, "fee_refresh", c.feeRefresh);
config.setString(s, "fee_refund", c.feeRefund); config.setString(s, "fee_refund", c.feeRefund);
config.setString(s, "rsa_keysize", `${c.rsaKeySize}`); if (c.cipher === "RSA") {
config.setString(s, "rsa_keysize", `${c.rsaKeySize}`);
config.setString(s, "cipher", "RSA");
} else if (c.cipher === "CS") {
config.setString(s, "cipher", "CS");
} else {
throw new Error();
}
} }
/** /**
@ -1328,6 +1335,7 @@ export class ExchangeService implements ExchangeServiceInterface {
helperCryptoRsaProc: ProcessWrapper | undefined; helperCryptoRsaProc: ProcessWrapper | undefined;
helperCryptoEddsaProc: ProcessWrapper | undefined; helperCryptoEddsaProc: ProcessWrapper | undefined;
helperCryptoCsProc: ProcessWrapper | undefined;
constructor( constructor(
private globalState: GlobalTestState, private globalState: GlobalTestState,
@ -1373,6 +1381,12 @@ export class ExchangeService implements ExchangeServiceInterface {
await cryptoEddsa.wait(); await cryptoEddsa.wait();
this.helperCryptoRsaProc = undefined; this.helperCryptoRsaProc = undefined;
} }
const cryptoCs = this.helperCryptoCsProc;
if (cryptoCs) {
cryptoCs.proc.kill("SIGTERM");
await cryptoCs.wait();
this.helperCryptoCsProc = undefined;
}
} }
/** /**
@ -1491,6 +1505,12 @@ export class ExchangeService implements ExchangeServiceInterface {
`exchange-crypto-eddsa-${this.name}`, `exchange-crypto-eddsa-${this.name}`,
); );
this.helperCryptoCsProc = this.globalState.spawnService(
"taler-exchange-secmod-cs",
["-c", this.configFilename, "-LDEBUG", ...this.timetravelArgArr],
`exchange-crypto-cs-${this.name}`,
);
this.helperCryptoRsaProc = this.globalState.spawnService( this.helperCryptoRsaProc = this.globalState.spawnService(
"taler-exchange-secmod-rsa", "taler-exchange-secmod-rsa",
["-c", this.configFilename, "-LDEBUG", ...this.timetravelArgArr], ["-c", this.configFilename, "-LDEBUG", ...this.timetravelArgArr],

View File

@ -76,6 +76,7 @@ export async function createMyTestkudosEnvironment(
await bank.pingUntilAvailable(); await bank.pingUntilAvailable();
const coinCommon = { const coinCommon = {
cipher: "RSA" as const,
durationLegal: "3 years", durationLegal: "3 years",
durationSpend: "2 years", durationSpend: "2 years",
durationWithdraw: "7 days", durationWithdraw: "7 days",

View File

@ -27,7 +27,7 @@ import {
setupDb, setupDb,
BankService, BankService,
delayMs, delayMs,
getPayto getPayto,
} from "../harness/harness.js"; } from "../harness/harness.js";
import { import {
withdrawViaBank, withdrawViaBank,
@ -97,6 +97,7 @@ async function createTestEnvironment(
await bank.pingUntilAvailable(); await bank.pingUntilAvailable();
const coin_u1: CoinConfig = { const coin_u1: CoinConfig = {
cipher: "RSA" as const,
durationLegal: "3 years", durationLegal: "3 years",
durationSpend: "2 years", durationSpend: "2 years",
durationWithdraw: "7 days", durationWithdraw: "7 days",

View File

@ -14,9 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { import { minimatch } from "@gnu-taler/taler-util";
minimatch
} from "@gnu-taler/taler-util";
import { import {
GlobalTestState, GlobalTestState,
runTestWithState, runTestWithState,
@ -88,6 +86,7 @@ import { runMerchantSpecPublicOrdersTest } from "./test-merchant-spec-public-ord
import { runExchangeTimetravelTest } from "./test-exchange-timetravel.js"; import { runExchangeTimetravelTest } from "./test-exchange-timetravel.js";
import { runDenomUnofferedTest } from "./test-denom-unoffered.js"; import { runDenomUnofferedTest } from "./test-denom-unoffered.js";
import { runWithdrawalFakebankTest } from "./test-withdrawal-fakebank.js"; import { runWithdrawalFakebankTest } from "./test-withdrawal-fakebank.js";
import { runClauseSchnorrTest } from "./test-clause-schnorr.js";
/** /**
* Test runner. * Test runner.
@ -106,6 +105,7 @@ interface TestMainFunction {
const allTests: TestMainFunction[] = [ const allTests: TestMainFunction[] = [
runBankApiTest, runBankApiTest,
runClaimLoopTest, runClaimLoopTest,
runClauseSchnorrTest,
runDepositTest, runDepositTest,
runDenomUnofferedTest, runDenomUnofferedTest,
runExchangeManagementTest, runExchangeManagementTest,