-
Notifications
You must be signed in to change notification settings - Fork 0
/
Proover.cs
89 lines (77 loc) · 3.17 KB
/
Proover.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
FiatShamirIdentification
Copyright 2015 Ivan Sarno
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//version V.2.2
using System;
using System.Numerics;
using System.Security.Cryptography;
namespace FiatShamirIdentification
{
/// <summary>
/// Object that interacts with a Verifier object to demonstrate possession of the private key
/// from which it derives the key of the Verifier.
/// Single iteration of protocol have error ratio = 1/2.
/// </summary>
public sealed class Proover
{
private readonly GeneratorWrap _generator;
private readonly PrivateKey _key;
private BigInteger _sessionNumber;
private bool _synch;
/// <summary>
/// </summary>
/// <param name="key">private key</param>
/// <param name="gen">random number generator, it is not disposed.</param>
internal Proover(PrivateKey key, RandomNumberGenerator gen)
{
_key = key;
_generator = new GeneratorWrap(gen, key.Size);
_synch = false;
}
/// <summary>
/// Start the protocol and return the init for Verifier.Step1.
/// </summary>
/// <returns>number to send to Verifier</returns>
public BigInteger Step1()
{
_synch = true;
_sessionNumber = _generator.GetBig() % _key.Modulus;
var square = _sessionNumber * _sessionNumber;
var squareMod = square % _key.Modulus;
//avoid comunication of the key
while (_sessionNumber < 3 && 1 != BigInteger.GreatestCommonDivisor(_sessionNumber, _key.Modulus) &&
1 != BigInteger.GreatestCommonDivisor(squareMod, _key.Modulus) && square == squareMod)
{
_sessionNumber = _generator.GetBig() % _key.Modulus;
square = _sessionNumber * _sessionNumber;
squareMod = square % _key.Modulus;
}
return squareMod;
}
/// <summary>
/// Take the result of Verifier.Step1() and return the proof to send to Verifier.
/// </summary>
/// <param name="choice">result of Verifier.Step1()</param>
/// <exception cref="InvalidOperationException"> Proover.Step2 is called before calling Proover.Step1</exception>
/// <returns>a number to send to Verifier</returns>
public BigInteger Step2(bool choice)
{
if (_synch)
_synch = false;
else throw new InvalidOperationException("Called Proover.Step2 before calling Proover.Step1");
if (choice)
return _sessionNumber * _key.Key % _key.Modulus;
return _sessionNumber;
}
}
}