

下記の定義を見ながら非対話ゼロ知識証明をc#で実装しています。

[RFC 8235 - Schnorr Non-interactive Zero-Knowledge Proof
日本語訳](https://tex2e.github.io/rfc-translater/html/rfc8235.html)

NIZKは、値rを計算する際に以下の数式を使用します。

[code]

    r = v - a * c % n
    
[/code]

このとき、値vは[1、n-1]の中からランダムに選んだ値を使う、と定義されていますが、例えばv=1の場合、rがマイナスの値となってしまい、必ず検証に失敗してしまいます。  
secp256k1を使用して、v=2^256以上の場合、検証が成功します。

値vの選択方法が間違っているのでしょうか？  
それとも、組んだプログラムに誤りがあるのでしょうか？  
ご存じの方がいらっしゃいましたら、ご指摘いただければ幸いです。

追記

再現コードを追加しました。

[code]

    // Use secp256k1
    // the order of G
    var n = BigInteger.Parse("0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141".AsSpan(), NumberStyles.HexNumber);
    // choose random a from [1, n-1]
    var a = n - 50;
    // choose random v from [1, n-1]
    var v = new BigInteger(9876);
    // hash
    var c = new BigInteger(123456);
    
    var r = v - a * c % n;
    
    Console.WriteLine(r);
    
[/code]

上記コードの出力は以下の通りです。

[code]

    -115792089237316195423570985008687907852837564279074904382605163141518155311661
    
[/code]

上記コードの計算式の計算順位を変更すると負数にはなりませんが、検証に失敗します。

[code]

    r = (v - a * c) % n;
    
[/code]

追記  
私が演算子%の動きを理解していませんでした。

[code]

    var modulus = (BigInteger a, BigInteger b) => (a % b + b) % b;
    
    var AA = new BigInteger(-1000);
    var BB = new BigInteger(3);
    
    var x1 = AA % BB;
    var x2 = modulus(AA, BB);
    
    // x1 = -1
    // x2 = 2
    
[/code]


CC BY-SA 4.0
2022-12-28T14:45:26.737
93079
2022-12-29T08:07:27.237
2022-12-29T08:07:27.237
56270
56270
question
c# 暗号理論
Schnorr NIZK Proof over Elliptic Curveの値rの計算がマイナスになってしまう