Failed Conditions
Push — v7 ( a687dc...e264c8 )
by Florent
02:28
created

EcDH::createMultiPartyKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
namespace Jose\Component\Core\Util\Ecc\Crypto\EcDH;
4
5
/**
6
 * *********************************************************************
7
 * Copyright (C) 2012 Matyas Danter
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining
10
 * a copy of this software and associated documentation files (the "Software"),
11
 * to deal in the Software without restriction, including without limitation
12
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
 * and/or sell copies of the Software, and to permit persons to whom the
14
 * Software is furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included
17
 * in all copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
23
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
 * OTHER DEALINGS IN THE SOFTWARE.
26
 * ***********************************************************************
27
 */
28
29
use Jose\Component\Core\Util\Ecc\Crypto\Key\PrivateKey;
30
use Jose\Component\Core\Util\Ecc\Crypto\Key\PublicKey;
31
use Jose\Component\Core\Util\Ecc\Math\GmpMath;
32
use Jose\Component\Core\Util\Ecc\Primitives\Point;
33
34
/**
35
 * This class is the implementation of ECDH.
36
 * EcDH is safe key exchange and achieves
37
 * that a key is transported securely between two parties.
38
 * The key then can be hashed and used as a basis in
39
 * a dual encryption scheme, along with AES for faster
40
 * two- way encryption.
41
 */
42
final class EcDH
43
{
44
    /**
45
     * Adapter used for math calculations
46
     *
47
     * @var GmpMath
48
     */
49
    private $adapter;
50
51
    /**
52
     * Secret key between the two parties
53
     *
54
     * @var Point
55
     */
56
    private $secretKey = null;
57
58
    /**
59
     *
60
     * @var PublicKey
61
     */
62
    private $recipientKey;
63
64
    /**
65
     *
66
     * @var PrivateKey
67
     */
68
    private $senderKey;
69
70
    /**
71
     * Initialize a new exchange from a generator point.
72
     *
73
     * @param GmpMath $adapter A math adapter instance.
74
     */
75
    public function __construct(GmpMath $adapter)
76
    {
77
        $this->adapter = $adapter;
78
    }
79
80
    /**
81
     * {@inheritDoc}
82
     * @see \Jose\Component\Core\Util\Ecc\Crypto\EcDH\EcDH::calculateSharedKey()
83
     */
84
    public function calculateSharedKey()
85
    {
86
        $this->calculateKey();
87
88
        return $this->secretKey->getX();
89
    }
90
91
    /**
92
     * {@inheritDoc}
93
     * @see \Jose\Component\Core\Util\Ecc\Crypto\EcDH\EcDH::createMultiPartyKey()
94
     */
95
    public function createMultiPartyKey()
96
    {
97
        $this->calculateKey();
98
99
        return new PublicKey($this->adapter, $this->senderKey->getPoint(), $this->secretKey);
100
    }
101
102
    /**
103
     * {@inheritDoc}
104
     * @see \Jose\Component\Core\Util\Ecc\Crypto\EcDH\EcDH::setRecipientKey()
105
     */
106
    public function setRecipientKey(PublicKey $key = null)
107
    {
108
        $this->recipientKey = $key;
109
        return $this;
110
    }
111
112
    /**
113
     * {@inheritDoc}
114
     * @see \Jose\Component\Core\Util\Ecc\Crypto\EcDH\EcDH::setSenderKey()
115
     */
116
    public function setSenderKey(PrivateKey $key)
117
    {
118
        $this->senderKey = $key;
119
        return $this;
120
    }
121
122
    /**
123
     *
124
     */
125
    private function calculateKey()
126
    {
127
        $this->checkExchangeState();
128
129
        if ($this->secretKey === null) {
130
            $this->secretKey = $this->recipientKey->getPoint()->mul($this->senderKey->getSecret());
131
        }
132
    }
133
134
    /**
135
     * Verifies that the shared secret is known, or that the required keys are available
136
     * to calculate the shared secret.
137
     * @throws \RuntimeException when the exchange has not been made.
138
     */
139
    private function checkExchangeState()
140
    {
141
        if ($this->secretKey !== null) {
142
            return;
143
        }
144
145
        if ($this->senderKey === null) {
146
            throw new \RuntimeException('Sender key not set.');
147
        }
148
149
        if ($this->recipientKey === null) {
150
            throw new \RuntimeException('Recipient key not set.');
151
        }
152
    }
153
}
154