I read several online document about implementing AVL tree using balance factor(Not using a height data field in Node structure), when insert into the tree, there is one case I could not figure out.
The document is from here(also from here has similar function) , the balance factor is defined as height(right-subtree) - height(left-subtree), value in [-1,0,1].
Insert method is implemented as :
public avlitem insertAVL(avlitem root, avlitem newstudent)
{
if(root == null) {
root = newstudent;
unbalance = true;
}
else if(root.idno == newstudent.idno)
System.err.println("No duplicates are allowed");
else if (root.idno > newstudent.idno)
{
root.leftchild=insertAVL(root.leftchild, newstudent);
if (unbalance )
{
switch(root.bfactor)
{ case -1:
root = balancefromleft(root);
unbalance=false;
break;
case 0:
root.bfactor = -1;
unbalance = true;
break;
case 1:
root.bfactor = 0;
unbalance = false;
}
}
}
else
{
root.rightchild=insertAVL(root.rightchild, newstudent);
if (unbalance )
{
switch(root.bfactor)
{
case -1 :
root.bfactor = 0;
unbalance = false;
break;
case 0:
root.bfactor=1;
unbalance = true;
break;
case 1 :
root = balancefromright(root);
unbalance = false;
}
}
}
return root;
}
And insert into the left child ,we use balancefromleft to reblance the tree:
public avlitem balancefromleft(avlitem root)
{
avlitem p;
avlitem w;
p = root.leftchild;
switch(p.bfactor)
{
case -1:
root.bfactor=0;
p.bfactor = 0;
root = rotatetoright(root);
break;
case 0 : System.err.println("can't balance from the left");break;
case 1 : w = p.rightchild;
{
switch (w.bfactor)
{
case -1:root.bfactor = 1;p.bfactor = 0;break;
case 0: root.bfactor = 0; p.bfactor = 0;break; // what is this case ?
case 1: root.bfactor = 0;p.bfactor = -1;
}
w.bfactor = 0;
p = rotatetoleft(p);
root.leftchild = p;
root = rotatetoright(root);
}
}
return root;
}
In the above balancefromleft function, we have a right rotate and double rotate case.
1)The right rotate case is : insert into left child of node y.
T1, T2, T3 and T4 are subtrees.
z y
/ \ / \
y T4 Right Rotate (z) x z
/ \ - - - - - - - - -> / \ / \
x T3 T1 T2 T3 T4
/ \
T1 T2
2) The left then right rotate case: insert into right child of y.
z z w
/ \ / \ / \
y T4 Left Rotate (y) w T4 Right Rotate(z) y z
/ \ - - - - - - - - -> / \ - - - - - - - -> / \ / \
T1 w y T3 T1 T2 T3 T4
/ \ / \
T2 T3 T1 T2
My question:
In the left-then-right rotate case, what case can cause the w.bfactor = 0 ?
In my mind, this could only be possible when remove node of T4 and T4 become shorter than before.How could it be possible when insert node ?
switch (w.bfactor)
{
case -1:root.bfactor = 1;p.bfactor = 0;break;
case 0: root.bfactor = 0; p.bfactor = 0;break; // what is this case ?
case 1: root.bfactor = 0;p.bfactor = -1;
}
Related
We are able to detect the collision but could not implement a snapping/magnetic effect like Snap edges of objects to each other and prevent overlap
we need help with 3D objects here and we are using Vec3 for the active object's position.
With the following approach, collision detection is working perfectly for all cases, and magnetic effect is somehow working - not perfectly.
It's working well when the object is moving along x or z-axis but when the object's movement is in diagonal direction (moving along x and z-axis simultaneously) that is where the problem comes.
Though am not satisfied with the following approach that's why am looking for new approach to implement both magnetic and collision detection features.
It is not necessary to have the solution in Threejs, any general solution or algorithm of coordinates can be converted into Threejs.
let collide = this.detectCollisionCubes(activeObject, collidingObject, vec3);
let magneticEffect = new MagneticEffect(activeObject, vec3, collidingObject);
vec3 = magneticEffect.setNewPosition();
activeObject.position.copy(vec3);
detectCollisionCubes = function(a, d, vec3){
// a is active object's positon
// d is colliding object
let aHeight = Math.abs(a.getHeight());
let aWidth = Math.abs(a.getWidth());
let aDepth = Math.abs(a.getDepth());
let b1 = vec3.y - aHeight / 2;
let t1 = vec3.y + aHeight / 2;
let r1 = vec3.x + aWidth / 2;
let l1 = vec3.x - aWidth / 2;
let f1 = vec3.z - aDepth / 2;
let B1 = vec3.z + aDepth / 2;
let dHeight = Math.abs(d.getHeight());
let dWidth = Math.abs(d.getWidth());
let dDepth = Math.abs(d.getDepth());
let b2 = d.position.y - dHeight / 2;
let t2 = d.position.y + dHeight / 2;
let r2 = d.position.x + dWidth / 2;
let l2 = d.position.x - dWidth / 2;
let f2 = d.position.z - dDepth / 2;
let B2 = d.position.z + dDepth / 2;
if (t1 < b2 || r1 < l2 || b1 > t2 || l1 > r2 || f1 > B2 || B1 < f2) {
return false;
}
return true;
}
Trying to create magnetic effect via
this.currentObject = currentObject;
this.collisionObject = collisionObject;
this.collisionType = null;
this.objectType = null;
this.currentPosition = currentPosition;
this.currentObjectHeight = Math.abs(currentObject.getHeight());
this.currentObjectWidth = Math.abs(currentObject.getWidth());
this.collisionObjectHeight = Math.abs(collisionObject.getHeight());
this.collisionObjectWidth = Math.abs(collisionObject.getWidth());
this.collisionObjectDepth = Math.abs(collisionObject.getDepth());
this.objectTop = currentObject.position.y + (this.currentObjectHeight/2);
this.objectBottom = currentObject.position.y - (this.currentObjectHeight/2);
this.collideTop = collisionObject.position.y + (this.collisionObjectHeight/2);
this.collideBottom = collisionObject.position.y - (this.collisionObjectHeight/2);
this.zAxisDifference = Math.abs(Math.abs(currentPosition.z) - Math.abs(collisionObject.position.z));
this.xAxisDifference = Math.abs(Math.abs(currentPosition.x) - Math.abs(collisionObject.position.x));
// Extra code here
if (
this.objectTop < this.collideBottom
) {
this.collisionType = collisionTypes.verticalBottom;
} else if (
this.objectBottom > this.collideTop
) {
this.collisionType = collisionTypes.verticalTop;
} else if (
this.currentPosition.x > this.collisionObject.position.x &&
this.zAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalXLeft;
} else if (
this.currentPosition.x < this.collisionObject.position.x &&
this.zAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalXRight;
} else if (
this.currentPosition.z > this.collisionObject.position.z &&
this.xAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalZLeft;
} else if (
this.currentPosition.z < this.collisionObject.position.z &&
this.xAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalZRight;
}
MagneticEffect.prototype.setNewPosition = function () {
if (this.collisionType === collisionTypes.verticalBottom) {
this.currentPosition.y = this.collideBottom + 0.5;
} else if (this.collisionType === collisionTypes.verticalTop) {
this.currentPosition.y = this.collideTop - 0.5;
} else if (this.collisionType === collisionTypes.horizentalXRight) {
this.currentPosition.x = this.collisionObject.position.x - this.collisionObjectWidth - 0.5;
} else if (this.collisionType === collisionTypes.horizentalXLeft) {
this.currentPosition.x = this.collisionObject.position.x + this.collisionObjectWidth + 0.5;
} else if (this.collisionType === collisionTypes.horizentalZRight) {
this.currentPosition.z = this.collisionObject.position.z - this.collisionObjectWidth - 0.5;
} else if (this.collisionType === collisionTypes.horizentalZLeft) {
this.currentPosition.z = this.collisionObject.position.z + this.collisionObjectWidth + 0.5;
}
return this.currentPosition;
};
I was reading Spark correlation algorithm source code and while going through the code, I coulddn't understand this particular peace of code.
This is from the file : org/apache/spark/mllib/linalg/BLAS.scala
def spr(alpha: Double, v: Vector, U: Array[Double]): Unit = {
val n = v.size
v match {
case DenseVector(values) =>
NativeBLAS.dspr("U", n, alpha, values, 1, U)
case SparseVector(size, indices, values) =>
val nnz = indices.length
var colStartIdx = 0
var prevCol = 0
var col = 0
var j = 0
var i = 0
var av = 0.0
while (j < nnz) {
col = indices(j)
// Skip empty columns.
colStartIdx += (col - prevCol) * (col + prevCol + 1) / 2
av = alpha * values(j)
i = 0
while (i <= j) {
U(colStartIdx + indices(i)) += av * values(i)
i += 1
}
j += 1
prevCol = col
}
}
}
I do not know Scala and that could be the reason I could not understand it. Can someone explain what is happening here.
It is being called from Rowmatrix.scala
def computeGramianMatrix(): Matrix = {
val n = numCols().toInt
checkNumColumns(n)
// Computes n*(n+1)/2, avoiding overflow in the multiplication.
// This succeeds when n <= 65535, which is checked above
val nt = if (n % 2 == 0) ((n / 2) * (n + 1)) else (n * ((n + 1) / 2))
// Compute the upper triangular part of the gram matrix.
val GU = rows.treeAggregate(new BDV[Double](nt))(
seqOp = (U, v) => {
BLAS.spr(1.0, v, U.data)
U
}, combOp = (U1, U2) => U1 += U2)
RowMatrix.triuToFull(n, GU.data)
}
The correlation is defined here:
https://en.wikipedia.org/wiki/Pearson_correlation_coefficient
The final goal is to understand the Spark correlation algorithm.
Update 1: Relevent paper https://stanford.edu/~rezab/papers/linalg.pdf
I'm using Alberto Santini's solution to this question to get a spiral grid reference based on an items index
Algorithm for iterating over an outward spiral on a discrete 2D grid from the origin
It's not the accepted solution, but it's the best for my needs as it avoids using a loop.
It's working well, but what I want now is to do the inverse. Based on a known x and y coordinate return the index of a location.
This is as a precursor to returning the items surrounding a given location.
Pascal code:
if y * y >= x * x then begin
p := 4 * y * y - y - x;
if y < x then
p := p - 2 * (y - x)
end
else begin
p := 4 * x * x - y - x;
if y < x then
p := p + 2 *(y - x)
end;
Description: Left-upper semi-diagonal (0-4-16-36-64) contains squared layer number (4 * layer^2). External if-statement defines layer and finds (pre-)result for position in corresponding row or column of left-upper semi-plane, and internal if-statement corrects result for mirror position.
I don't know if there is a concise mathematical equation to derive what you want, but I have a solution that computes what you want in O(1) time per query. No loops like you wanted.
My approach :
(i) For any given point (x,y), find the number of points which lie in the square of side length (2*a-1), where a = Max( |x|, |y| ). These are the interior points. i.e, the number of points lying in all spirals NOT including current spiral.
This is nothing but ( 2*a -1 )*( 2*a -1 )
Eg : Consider the following diagram :
y
|
|
16 15 14 13 12
17 4 3 2 11
-- 18 5 0 1 10 --- x
19 6 7 8 9
20 21 22 23 24
|
|
For the point ( 2,1 ), a = 2. The interior points, here are labelled as 0, 1, 2, 3, 4, 5, 6, 7, 8 - The square with edge length 3
(ii) Now compute the points lying on the current spiral. The spiral has 4 "corner" points -
(a) The starting point ( where the current spiral starts )
(b) The point ( a, a )
(c) The point ( -a, a )
(d) The point ( -a, -a )
So, I compute the number of elements lying between each such pair [ i.e, between (a) and (b), (b) and (c), (c) and (d) ], such that all of these fall before the required input point in the spiral sequence. This can be done by simple subtraction of point co-ordinates.
This value, plus the number of interior points will give you the required answer.
I am not sure whether I have explained this very clearly. Do let me know if you require any clarifications or further explanation.
Attached is the JAVA code I wrote to test my logic. I am sorry but it is not very elegant, but it works :P
import java.io.IOException;
import java.util.Scanner;
class Pnt
{
int x, y;
public Pnt( int _x, int _y )
{
x = _x;
y = _y;
}
}
public class Spiral
{
static int interior( Pnt p ) // returns points within interior square of side length MAX( x, y ) - 1
{
int a = Math.max( Math.abs( p.x ), Math.abs( p.y ));
return ( 2*a - 1 )*( 2*a - 1 );
}
static Pnt startPnt( Pnt p ) // first point in that spiral
{
int a = Math.max( Math.abs( p.x ), Math.abs( p.y ));
// last pnt in prev spiral = [ a-1, -( a-1 ) ]
// next pnt = [ a, -( a-1 ) ]
return new Pnt( a, -( a-1 ));
}
static int offSetRow1( Pnt pStart, Pnt p )
{
return ( p.y - pStart.y ) + 1;
}
static int solve( Pnt curr )
{
// check location of curr
// It may lie on 1st row, 2nd row, 3rd or 4th row
int a = Math.max( Math.abs( curr.x ), Math.abs( curr.y ));
int off=0;
int interiorCnt = interior( curr );
Pnt start = startPnt( curr );
if( ( curr.x == a ) && ( curr.y >= start.y ) ) // row 1
{
off = offSetRow1( start, curr );
return off+interiorCnt;
}
if( curr.y == a ) // row 2
{
Pnt start2 = new Pnt( a, a );
int off1 = offSetRow1( start, start2 );
// now add diff in x-coordinates
int off2 = start2.x - curr.x;
off = off1 + off2;
return off+interiorCnt;
}
if( curr.x == -a ) // row 3
{
Pnt start2 = new Pnt( a, a );
int off1 = offSetRow1( start, start2 );
// now add diff in x-coordinates
Pnt start3 = new Pnt( -a, a );
int off2 = start2.x - start3.x;
// now add diff in y co-ordinates
int off3 = start3.y - curr.y;
off = off1 + off2 + off3;
return off+interiorCnt;
}
else // row 4
{
Pnt start2 = new Pnt( a, a );
int off1 = offSetRow1( start, start2 );
// now add diff in x-coordinates
Pnt start3 = new Pnt( -a, a );
int off2 = start2.x - start3.x;
// now add diff in y co-ordinates
int off3 = start3.y - curr.y;
Pnt start4 = new Pnt( -a, -a );
// add diff in x co-ordinates
int off4 = curr.x - start4.x;
off = off1 + off2 + off3 + off4;
return interiorCnt + off;
}
}
public static void main( String[] args ) throws IOException
{
Scanner s = new Scanner( System.in );
while( true )
{
int x = s.nextInt();
int y = s.nextInt();
Pnt curr = new Pnt( x, y );
System.out.println( solve( curr ));
}
}
}
I want to throw in my function since it's a bit more concise than the last solution but more complex than the first.
rather than have the indexes adjacent to each-other, my code opts for loops/layers where the first index of the next loop is always on the same axis.
like so:
23 24 9 10 11 +y
22 8 1 2 12
21 7 0 3 13
20 6 5 4 14
19 18 17 16 15 -y
-x +x
it has set directions and uses the smaller vec2 value as the offset from these NSEW axes
func translate_vector2_to_spiral_index(vec2):
#layer is the ring level the position is on
var layer = max(abs(vec2.x),abs(vec2.y))
if layer == 0:
return 0
#the total interior positions before the edge
var base_index = 0
var i = 0
while i < layer:
base_index += 8 * i
i+=1
var current_layer_total = 8 * i
#non_axis spaces at each corner (not directly any nesw axis)
var non_axis_spaces = (current_layer_total - 4)/4
#direct axes spaces on this layer
var N = 1
var E = N + non_axis_spaces + 1
var S = E + non_axis_spaces + 1
var W = S + non_axis_spaces + 1
var spiral_index = base_index
if abs(vec2.x) > abs(vec2.y):
if vec2.x < 0:
spiral_index+=W
spiral_index += vec2.y
elif vec2.x > 0:
spiral_index+=E
spiral_index -= vec2.y
else:
if vec2.y < 0:
spiral_index+=S
elif vec2.y > 0:
spiral_index+=N
#abs(y) must be equivalent to layers if x is 0
else:
if vec2.y < 0:
spiral_index+=S
spiral_index -= vec2.x
elif vec2.y > 0:
spiral_index
var x = N
x += vec2.x
#if x goes into the negative on the iteration axis (N) it's a subtraction from the layer total
if vec2.x < 0:
x = current_layer_total + 1 + vec2.x
spiral_index += x
else:
if vec2.x < 0:
spiral_index+=W
elif vec2.x > 0:
spiral_index+=E
#abs(x) must be equivalent to layers if y is 0
return spiral_index
there's probably a way to shorten this but i thought to throw this out there.
I'm using Alberto Santini's solution to this question to get a spiral grid reference based on an items index
Algorithm for iterating over an outward spiral on a discrete 2D grid from the origin
It's not the accepted solution, but it's the best for my needs as it avoids using a loop.
It's working well, but what I want now is to do the inverse. Based on a known x and y coordinate return the index of a location.
This is as a precursor to returning the items surrounding a given location.
Pascal code:
if y * y >= x * x then begin
p := 4 * y * y - y - x;
if y < x then
p := p - 2 * (y - x)
end
else begin
p := 4 * x * x - y - x;
if y < x then
p := p + 2 *(y - x)
end;
Description: Left-upper semi-diagonal (0-4-16-36-64) contains squared layer number (4 * layer^2). External if-statement defines layer and finds (pre-)result for position in corresponding row or column of left-upper semi-plane, and internal if-statement corrects result for mirror position.
I don't know if there is a concise mathematical equation to derive what you want, but I have a solution that computes what you want in O(1) time per query. No loops like you wanted.
My approach :
(i) For any given point (x,y), find the number of points which lie in the square of side length (2*a-1), where a = Max( |x|, |y| ). These are the interior points. i.e, the number of points lying in all spirals NOT including current spiral.
This is nothing but ( 2*a -1 )*( 2*a -1 )
Eg : Consider the following diagram :
y
|
|
16 15 14 13 12
17 4 3 2 11
-- 18 5 0 1 10 --- x
19 6 7 8 9
20 21 22 23 24
|
|
For the point ( 2,1 ), a = 2. The interior points, here are labelled as 0, 1, 2, 3, 4, 5, 6, 7, 8 - The square with edge length 3
(ii) Now compute the points lying on the current spiral. The spiral has 4 "corner" points -
(a) The starting point ( where the current spiral starts )
(b) The point ( a, a )
(c) The point ( -a, a )
(d) The point ( -a, -a )
So, I compute the number of elements lying between each such pair [ i.e, between (a) and (b), (b) and (c), (c) and (d) ], such that all of these fall before the required input point in the spiral sequence. This can be done by simple subtraction of point co-ordinates.
This value, plus the number of interior points will give you the required answer.
I am not sure whether I have explained this very clearly. Do let me know if you require any clarifications or further explanation.
Attached is the JAVA code I wrote to test my logic. I am sorry but it is not very elegant, but it works :P
import java.io.IOException;
import java.util.Scanner;
class Pnt
{
int x, y;
public Pnt( int _x, int _y )
{
x = _x;
y = _y;
}
}
public class Spiral
{
static int interior( Pnt p ) // returns points within interior square of side length MAX( x, y ) - 1
{
int a = Math.max( Math.abs( p.x ), Math.abs( p.y ));
return ( 2*a - 1 )*( 2*a - 1 );
}
static Pnt startPnt( Pnt p ) // first point in that spiral
{
int a = Math.max( Math.abs( p.x ), Math.abs( p.y ));
// last pnt in prev spiral = [ a-1, -( a-1 ) ]
// next pnt = [ a, -( a-1 ) ]
return new Pnt( a, -( a-1 ));
}
static int offSetRow1( Pnt pStart, Pnt p )
{
return ( p.y - pStart.y ) + 1;
}
static int solve( Pnt curr )
{
// check location of curr
// It may lie on 1st row, 2nd row, 3rd or 4th row
int a = Math.max( Math.abs( curr.x ), Math.abs( curr.y ));
int off=0;
int interiorCnt = interior( curr );
Pnt start = startPnt( curr );
if( ( curr.x == a ) && ( curr.y >= start.y ) ) // row 1
{
off = offSetRow1( start, curr );
return off+interiorCnt;
}
if( curr.y == a ) // row 2
{
Pnt start2 = new Pnt( a, a );
int off1 = offSetRow1( start, start2 );
// now add diff in x-coordinates
int off2 = start2.x - curr.x;
off = off1 + off2;
return off+interiorCnt;
}
if( curr.x == -a ) // row 3
{
Pnt start2 = new Pnt( a, a );
int off1 = offSetRow1( start, start2 );
// now add diff in x-coordinates
Pnt start3 = new Pnt( -a, a );
int off2 = start2.x - start3.x;
// now add diff in y co-ordinates
int off3 = start3.y - curr.y;
off = off1 + off2 + off3;
return off+interiorCnt;
}
else // row 4
{
Pnt start2 = new Pnt( a, a );
int off1 = offSetRow1( start, start2 );
// now add diff in x-coordinates
Pnt start3 = new Pnt( -a, a );
int off2 = start2.x - start3.x;
// now add diff in y co-ordinates
int off3 = start3.y - curr.y;
Pnt start4 = new Pnt( -a, -a );
// add diff in x co-ordinates
int off4 = curr.x - start4.x;
off = off1 + off2 + off3 + off4;
return interiorCnt + off;
}
}
public static void main( String[] args ) throws IOException
{
Scanner s = new Scanner( System.in );
while( true )
{
int x = s.nextInt();
int y = s.nextInt();
Pnt curr = new Pnt( x, y );
System.out.println( solve( curr ));
}
}
}
I want to throw in my function since it's a bit more concise than the last solution but more complex than the first.
rather than have the indexes adjacent to each-other, my code opts for loops/layers where the first index of the next loop is always on the same axis.
like so:
23 24 9 10 11 +y
22 8 1 2 12
21 7 0 3 13
20 6 5 4 14
19 18 17 16 15 -y
-x +x
it has set directions and uses the smaller vec2 value as the offset from these NSEW axes
func translate_vector2_to_spiral_index(vec2):
#layer is the ring level the position is on
var layer = max(abs(vec2.x),abs(vec2.y))
if layer == 0:
return 0
#the total interior positions before the edge
var base_index = 0
var i = 0
while i < layer:
base_index += 8 * i
i+=1
var current_layer_total = 8 * i
#non_axis spaces at each corner (not directly any nesw axis)
var non_axis_spaces = (current_layer_total - 4)/4
#direct axes spaces on this layer
var N = 1
var E = N + non_axis_spaces + 1
var S = E + non_axis_spaces + 1
var W = S + non_axis_spaces + 1
var spiral_index = base_index
if abs(vec2.x) > abs(vec2.y):
if vec2.x < 0:
spiral_index+=W
spiral_index += vec2.y
elif vec2.x > 0:
spiral_index+=E
spiral_index -= vec2.y
else:
if vec2.y < 0:
spiral_index+=S
elif vec2.y > 0:
spiral_index+=N
#abs(y) must be equivalent to layers if x is 0
else:
if vec2.y < 0:
spiral_index+=S
spiral_index -= vec2.x
elif vec2.y > 0:
spiral_index
var x = N
x += vec2.x
#if x goes into the negative on the iteration axis (N) it's a subtraction from the layer total
if vec2.x < 0:
x = current_layer_total + 1 + vec2.x
spiral_index += x
else:
if vec2.x < 0:
spiral_index+=W
elif vec2.x > 0:
spiral_index+=E
#abs(x) must be equivalent to layers if y is 0
return spiral_index
there's probably a way to shorten this but i thought to throw this out there.
I implemented this and am getting error:0407B07B:rsa routines:RSA_check_key:d e not congruent to 1
BitLen 1024, ModLen 128, Prime1,Prime2,Exponent1,Exponent2,Coefficient lengths =64
PrivateExponent Len = 128
RSA* blobtorsa()
{
BN_set_word(rsa->e, prsahdr->pubexp);
lend_tobn(rsa->n, pbmod, cbmod);
lend_tobn(rsa->p, pbprime1, cbprimes);
lend_tobn(rsa->q, pbprime2, cbprimes);
lend_tobn(rsa->d, pbprivexp, cbprivexp);
// d mod ( p - 1 )
BN_mod_sub(rsa->dmp1, rsa->d, BN_value_one(), rsa->p, ctx);
// d mod (q-1)
BN_mod_sub(rsa->dmq1, rsa->d, BN_value_one(), rsa->q, ctx);
BIGNUM* negone = BN_new();
BN_set_word(negone, -1);
// q^-1 mod p
BN_mod_exp(rsa->iqmp, rsa->q, negone, rsa->p, ctx);
if ( RSA_check_key(rsa) == 0 )
{
print error
error:0407B07B:rsa routines:RSA_check_key:d e not congruent to 1
}
}
For anyone else wondering - once you get the pointers and size to the separate
items in the structure:
{
BIGNUM* temp = BN_new();
rsa->e = BN_new();
BN_set_word(rsa->e, prsapk->pubexp);
// set n, p, q and d from structures
rsa->n = BN_new();
lend_tobn(rsa->n, pbMod, cbMod);
rsa->p = BN_new();
lend_tobn(rsa->p, pbPrime1, cbPrime1);
rsa->q = BN_new();
lend_tobn(rsa->q, pbPrime2, cbPrime2);
rsa->d = BN_new();
lend_tobn(rsa->d, pbPrivateExponent, cbPrivateExponent);
// calculate the remainder of properties
// d mod (p-1)
rsa->dmp1 = BN_new();
BN_copy(temp, rsa->p);
BN_sub_word(temp, 1);
BN_mod(rsa->dmp1, rsa->d, temp, ctx);
// d mod (q-1)
rsa->dmq1 = BN_new();
BN_copy(temp, rsa->q);
BN_sub_word(temp, 1);
BN_mod(rsa->dmq1, rsa->d, temp, ctx);
// q^-1 mod p
rsa->iqmp = BN_new();
BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx);
BN_free(temp);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
ERR_clear_error();
if ( RSA_check_key(rsa) == 1 )
{
}
}