public PromiseClientSession(PromiseParameters parameters, State state) : this(parameters) { if (state == null) { return; } InternalState = Serializer.Clone(state); if (InternalState.Commitments != null) { _Hashes = new HashBase[InternalState.Commitments.Length]; int fakeI = 0, realI = 0; for (int i = 0; i < _Hashes.Length; i++) { HashBase hash = null; if (InternalState.FakeIndexes != null && InternalState.FakeIndexes.Contains(i)) { hash = new FakeHash(_Parameters) { Salt = InternalState.FakeSalts[fakeI++] }; } else { hash = new RealHash(InternalState.Cashout, InternalState.EscrowedCoin) { FeeVariation = InternalState.FeeVariations[realI++] }; } hash.Index = i; hash.Commitment = InternalState.Commitments[i]; _Hashes[i] = hash; } } }
public void SetKey(String stringKey) { if (String.IsNullOrWhiteSpace(stringKey)) { throw new ArgumentException("Argument must be not null and not whitespace", nameof(stringKey)); } stringKey = stringKey.Trim(); _key = HashBase.HashWithIterations(256, _sha256, Encoding.UTF8.GetBytes(stringKey)); }
private bool IsValidSignature(PuzzleSolution solution, HashBase hash, out ECDSASignature signature) { signature = null; var escrow = EscrowScriptPubKeyParameters.GetFromCoin(InternalState.EscrowedCoin); try { var key = new XORKey(solution); signature = new ECDSASignature(key.XOR(hash.Commitment.Promise)); var ok = escrow.Initiator.Verify(hash.GetHash(), signature); if (!ok) { signature = null; } return(ok); } catch { } return(false); }
private HashBase[][] _Hashes; // The list of Hashes (Beta_i in the paper) public PromiseClientSession(PromiseParameters parameters, State state) : this(parameters) { if (state == null) { return; } InternalState = Serializer.Clone(state); if (InternalState.Commitments != null) { _Hashes = new HashBase[parameters.PaymentsCount][]; for (int i = 0; i < _Hashes.Length; i++) { _Hashes[i] = new HashBase[InternalState.Commitments[i].Length]; int fakeJ = 0, realJ = 0; for (int j = 0; j < _Hashes[i].Length; j++) { HashBase hash = null; if (InternalState.FakeColumns != null && InternalState.FakeColumns.Contains(j)) { hash = new FakeHash(parameters) { Salt = InternalState.Salts[i][fakeJ++] }; } else { hash = new RealHash(InternalState.Cashout, InternalState.EscrowedCoin) { FeeVariation = InternalState.FeeVariations[i][realJ++] }; } hash.Index = j; hash.Commitment = InternalState.Commitments[i][j]; _Hashes[i][j] = hash; } } } }
private bool IsValidSignature(PuzzleSolution solution, HashBase hash, out PubKey signer, out ECDSASignature signature) { signer = null; signature = null; try { var key = new XORKey(solution); signature = new ECDSASignature(key.XOR(hash.Commitment.Promise)); foreach (var sig in GetExpectedSigners()) { if (sig.Verify(hash.GetHash(), signature)) { signer = sig; return(true); } } return(false); } catch { } return(false); }
public SignaturesRequest CreateSignatureRequest(Script cashoutDestination, FeeRate feeRate) { // Steps 2-4 // Almost done, just need to figure out the Transaction CashOut things. if (cashoutDestination == null) { throw new ArgumentNullException(nameof(cashoutDestination)); } if (feeRate == null) { throw new ArgumentNullException(nameof(feeRate)); } AssertState(PromiseClientStates.WaitingSignatureRequest); Transaction cashout = new Transaction(); // TODO: Figure out the cashout format to give j Bitcoins to Bob and Q-J to the Tumbler cashout.AddInput(new TxIn(InternalState.EscrowedCoin.Outpoint)); cashout.Inputs[0].ScriptSig = new Script( Op.GetPushOp(TrustedBroadcastRequest.PlaceholderSignature), Op.GetPushOp(TrustedBroadcastRequest.PlaceholderSignature), Op.GetPushOp(InternalState.EscrowedCoin.Redeem.ToBytes()) ); cashout.AddOutput(new TxOut(InternalState.EscrowedCoin.Amount, cashoutDestination)); cashout.Outputs[0].Value -= feeRate.GetFee(cashout.GetVirtualSize()); // If each payment level requires a different cashOut, then this // should be moved to the first loop. HashBase[][] hashes = new HashBase[_Parameters.PaymentsCount][]; //2D for (int i = 0; i < _Parameters.PaymentsCount; i++) { hashes[i] = new HashBase[_Parameters.GetTotalTransactionsCountPerLevel()]; for (int j = 0; j < Parameters.RealTransactionCountPerLevel; j++) { RealHash h = new RealHash(cashout, InternalState.EscrowedCoin) { FeeVariation = Money.Satoshis(i) }; hashes[i][j] = h; } for (int j = Parameters.RealTransactionCountPerLevel; j < hashes[i].Length; j++) { FakeHash h = new FakeHash(Parameters) { Salt = new uint256(RandomUtils.GetBytes(32)) }; hashes[i][j] = h; } } _Hashes = hashes; // Under the assumption that given the same seed the Shuffle will be deterministic. // TODO: Verify this in Debugging or a unit test. var shuffleSeed = RandomUtils.GetInt32(); for (int i = 0; i < _Parameters.PaymentsCount; i++) { NBitcoin.Utils.Shuffle(_Hashes[i], shuffleSeed); } for (int i = 0; i < _Parameters.PaymentsCount; i++) { for (int j = 0; j < _Hashes[i].Length; j++) { _Hashes[i][j].Index = j; } } var fakeIndices = _Hashes.First().OfType <FakeHash>().Select(h => h.Index).ToArray(); uint256 indexSalt = null; var request = new SignaturesRequest { // This looks cool, but double check the use of Select in debugging. Hashes = _Hashes.Select(h => (h.Select(k => k.GetHash()).ToArray())).ToArray(), FakeIndexesHash = PromiseUtils.HashIndexes(ref indexSalt, fakeIndices), }; InternalState.IndexSalt = indexSalt; InternalState.Cashout = cashout.Clone(); InternalState.Status = PromiseClientStates.WaitingCommitments; InternalState.FakeColumns = fakeIndices; return(request); }