feat: schnorr check in wasm
This commit is contained in:
parent
9431b294c6
commit
8d6cdb3868
@ -2,7 +2,15 @@ import "./index.css";
|
||||
import "@szhsin/react-menu/dist/index.css";
|
||||
import "./fonts/inter.css";
|
||||
|
||||
import { compress, expand_filter, flat_merge, get_diff, pow, default as wasmInit } from "@snort/system-wasm";
|
||||
import {
|
||||
compress,
|
||||
expand_filter,
|
||||
flat_merge,
|
||||
get_diff,
|
||||
pow,
|
||||
schnorr_verify,
|
||||
default as wasmInit,
|
||||
} from "@snort/system-wasm";
|
||||
import WasmPath from "@snort/system-wasm/pkg/system_wasm_bg.wasm";
|
||||
|
||||
import { StrictMode } from "react";
|
||||
@ -76,6 +84,9 @@ const WasmQueryOptimizer = {
|
||||
compress: (all: Array<ReqFilter>) => {
|
||||
return compress(all) as Array<ReqFilter>;
|
||||
},
|
||||
schnorrVerify: (id, sig, pubkey) => {
|
||||
return schnorr_verify(id, sig, pubkey);
|
||||
},
|
||||
} as QueryOptimizer;
|
||||
|
||||
export class WasmPowWorker implements PowMiner {
|
||||
|
19
packages/system-wasm/Cargo.lock
generated
19
packages/system-wasm/Cargo.lock
generated
@ -644,6 +644,24 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "secp256k1"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2acea373acb8c21ecb5a23741452acd2593ed44ee3d343e72baaa143bc89d0d5"
|
||||
dependencies = [
|
||||
"secp256k1-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "secp256k1-sys"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dd97a086ec737e30053fd5c46f097465d25bb81dd3608825f65298c4c98be83"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.188"
|
||||
@ -736,6 +754,7 @@ dependencies = [
|
||||
"hex",
|
||||
"itertools 0.11.0",
|
||||
"rand",
|
||||
"secp256k1",
|
||||
"serde",
|
||||
"serde-wasm-bindgen",
|
||||
"serde_json",
|
||||
|
@ -12,6 +12,7 @@ argon2 = "0.5.2"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
hex = { version = "0.4.3", features = [], default-features = false }
|
||||
itertools = "0.11.0"
|
||||
secp256k1 = "0.28.0"
|
||||
serde = { version = "1.0.188", features = ["derive"], default-features = false }
|
||||
serde-wasm-bindgen = "0.5.0"
|
||||
sha256 = { version = "1.4.0", features = [], default-features = false }
|
||||
|
12
packages/system-wasm/pkg/system_wasm.d.ts
vendored
12
packages/system-wasm/pkg/system_wasm.d.ts
vendored
@ -39,6 +39,13 @@ export function pow(val: any, target: any): any;
|
||||
* @returns {any}
|
||||
*/
|
||||
export function argon2(password: any, salt: any): any;
|
||||
/**
|
||||
* @param {any} hash
|
||||
* @param {any} sig
|
||||
* @param {any} pub_key
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function schnorr_verify(hash: any, sig: any, pub_key: any): boolean;
|
||||
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
@ -51,6 +58,11 @@ export interface InitOutput {
|
||||
readonly compress: (a: number, b: number) => void;
|
||||
readonly pow: (a: number, b: number, c: number) => void;
|
||||
readonly argon2: (a: number, b: number, c: number) => void;
|
||||
readonly schnorr_verify: (a: number, b: number, c: number, d: number) => void;
|
||||
readonly rustsecp256k1_v0_9_1_context_create: (a: number) => number;
|
||||
readonly rustsecp256k1_v0_9_1_context_destroy: (a: number) => void;
|
||||
readonly rustsecp256k1_v0_9_1_default_illegal_callback_fn: (a: number, b: number) => void;
|
||||
readonly rustsecp256k1_v0_9_1_default_error_callback_fn: (a: number, b: number) => void;
|
||||
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
||||
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||
|
@ -361,6 +361,28 @@ export function argon2(password, salt) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} hash
|
||||
* @param {any} sig
|
||||
* @param {any} pub_key
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function schnorr_verify(hash, sig, pub_key) {
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
wasm.schnorr_verify(retptr, addHeapObject(hash), addHeapObject(sig), addHeapObject(pub_key));
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
var r2 = getInt32Memory0()[retptr / 4 + 2];
|
||||
if (r2) {
|
||||
throw takeObject(r1);
|
||||
}
|
||||
return r0 !== 0;
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(f, args) {
|
||||
try {
|
||||
return f.apply(this, args);
|
||||
|
Binary file not shown.
@ -8,6 +8,11 @@ export function flat_merge(a: number, b: number): void;
|
||||
export function compress(a: number, b: number): void;
|
||||
export function pow(a: number, b: number, c: number): void;
|
||||
export function argon2(a: number, b: number, c: number): void;
|
||||
export function schnorr_verify(a: number, b: number, c: number, d: number): void;
|
||||
export function rustsecp256k1_v0_9_1_context_create(a: number): number;
|
||||
export function rustsecp256k1_v0_9_1_context_destroy(a: number): void;
|
||||
export function rustsecp256k1_v0_9_1_default_illegal_callback_fn(a: number, b: number): void;
|
||||
export function rustsecp256k1_v0_9_1_default_error_callback_fn(a: number, b: number): void;
|
||||
export function __wbindgen_malloc(a: number, b: number): number;
|
||||
export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number;
|
||||
export function __wbindgen_add_to_stack_pointer(a: number): number;
|
||||
|
@ -1,6 +1,7 @@
|
||||
extern crate console_error_panic_hook;
|
||||
|
||||
use argon2::{Argon2};
|
||||
use secp256k1::{Message, Secp256k1, XOnlyPublicKey};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::filter::{FlatReqFilter, ReqFilter};
|
||||
use wasm_bindgen::prelude::*;
|
||||
@ -98,6 +99,20 @@ pub fn argon2(password: JsValue, salt: JsValue) -> Result<JsValue, JsValue> {
|
||||
Ok(serde_wasm_bindgen::to_value(&hex::encode(key))?)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn schnorr_verify(hash: JsValue, sig: JsValue, pub_key: JsValue) -> Result<bool, JsValue> {
|
||||
console_error_panic_hook::set_once();
|
||||
let msg_hex: String = serde_wasm_bindgen::from_value(hash)?;
|
||||
let sig_hex: String = serde_wasm_bindgen::from_value(sig)?;
|
||||
let pub_key_hex: String = serde_wasm_bindgen::from_value(pub_key)?;
|
||||
|
||||
let secp = Secp256k1::new();
|
||||
let msg = Message::from_digest_slice(&hex::decode(msg_hex).unwrap()).unwrap();
|
||||
let key = XOnlyPublicKey::from_slice(&hex::decode(pub_key_hex).unwrap()).unwrap();
|
||||
let sig = secp256k1::schnorr::Signature::from_slice(&hex::decode(sig_hex).unwrap()).unwrap();
|
||||
Ok(secp.verify_schnorr(&sig, &msg, &key).is_ok())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -199,9 +199,12 @@ export class NostrSystem extends EventEmitter<NostrSystemEvents> implements Syst
|
||||
this.#log("Rejecting invalid event %O", ev);
|
||||
return;
|
||||
}
|
||||
if (this.checkSigs && !EventExt.verify(ev)) {
|
||||
this.#log("Invalid sig %O", ev);
|
||||
return;
|
||||
if (this.checkSigs) {
|
||||
const id = EventExt.createId(ev);
|
||||
if (!this.#queryOptimizer.schnorrVerify(id, ev.sig, ev.pubkey)) {
|
||||
this.#log("Invalid sig %O", ev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (const [, v] of this.Queries) {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { schnorr } from "@noble/curves/secp256k1";
|
||||
import { ReqFilter } from "../nostr";
|
||||
import { expandFilter } from "./request-expander";
|
||||
import { flatMerge, mergeSimilar } from "./request-merger";
|
||||
@ -24,6 +25,7 @@ export interface QueryOptimizer {
|
||||
getDiff(prev: Array<ReqFilter>, next: Array<ReqFilter>): Array<FlatReqFilter>;
|
||||
flatMerge(all: Array<FlatReqFilter>): Array<ReqFilter>;
|
||||
compress(all: Array<ReqFilter>): Array<ReqFilter>;
|
||||
schnorrVerify(hash: string, sig: string, pubkey: string): boolean;
|
||||
}
|
||||
|
||||
export const DefaultQueryOptimizer = {
|
||||
@ -43,4 +45,7 @@ export const DefaultQueryOptimizer = {
|
||||
compress: (all: Array<ReqFilter>) => {
|
||||
return mergeSimilar(all);
|
||||
},
|
||||
schnorrVerify: (hash, sig, pubkey) => {
|
||||
return schnorr.verify(sig, hash, pubkey);
|
||||
},
|
||||
} as QueryOptimizer;
|
||||
|
Loading…
x
Reference in New Issue
Block a user